Libraries used in the Project and uploading data
library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
method from
print.tbl_lazy
print.tbl_sql
── Attaching packages ──────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
✓ ggplot2 3.3.3 ✓ purrr 0.3.4
✓ tibble 3.0.3 ✓ dplyr 1.0.2
✓ tidyr 1.1.2 ✓ stringr 1.4.0
✓ readr 1.4.0 ✓ forcats 0.5.0
── Conflicts ─────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag() masks stats::lag()
library(dplyr)
library(stringr)
library(svMisc)
Attaching package: ‘svMisc’
The following object is masked from ‘package:utils’:
?
library(ggplot2)
library(gtable)
library("ggpubr")
Registered S3 method overwritten by 'data.table':
method from
print.data.table
log_data <- read_csv("~/Desktop/PAE/github/data/logData.csv")
── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────────────────
cols(
callerId = col_double(),
langId = col_double(),
callTime = col_datetime(format = ""),
lastCallTime = col_character(),
noCallsMade = col_double(),
noContentListened = col_double(),
callId = col_character(),
eventTime = col_datetime(format = ""),
logInfo = col_character(),
logInfoId = col_double(),
inSurvey = col_logical()
)
#log_data <- read_csv("~/Desktop/PAE/github/data/benData_weakCallers.csv")
log_data_saver <- log_data
log_data <- unique(log_data)
log_data$logInfo <- str_replace(log_data$logInfo, " ", " ")
#MAKE IT ALL UPPER!!!
log_data$logInfo <- toupper(log_data$logInfo)
### GETTING THE DATE MONTH AND YEAR IF I WANT!!!
extractdate <- function(date) {
day <- format(date, format="%d")
month <- format(date, format="%m")
year <- format(date, format="%Y")
cbind(day, month, year)
}
#making first calls
first_call<-extractdate(log_data$callTime)
#making last call
last_day <-substr(log_data$eventTime, 9, 10)
last_month <- substr(log_data$eventTime, 6, 7)
last_year <-substr(log_data$eventTime, 1, 4)
log_data<-cbind(log_data, first_call,last_day,last_month,last_year)
#Converting columns to numeric
log_data$day <-as.numeric(log_data$day)
log_data$last_day <- as.numeric(log_data$last_day)
log_data$month <-as.numeric(log_data$month)
log_data$last_month <- as.numeric(log_data$last_month)
log_data$year <- as.numeric(log_data$year)
log_data$last_year <- as.numeric(log_data$last_year )
log_data$year <- log_data$year +log_data$month/12
log_data$last_year <- log_data$last_year + log_data$last_month/12
log_data$caller_lifetime <- log_data$last_year - log_data$year
Cmd+Option+I.
Cmd+Shift+K
PRELIMINARY DISTRIBUTIONS
In this section, we display some of the basic distributions of the data including languages, total lifeetime of a given caller, colls made, content accessed, and the ratio of content listened to calls made.
Based on the graphs below, we are nervous that some of the data is not random given the incredibly high ratio for content listened to calls made, but given that the data is distributed fairly evenly across thee different graphs, we are unsure
lang_spoken <- log_data %>%
group_by(callerId, langId) %>%
count()
#Distribution of languages spoken
ggplot(data=lang_spoken, aes(x=langId)) +
geom_bar(fill='red')+
geom_text(stat='count', aes(label=..count../16445), vjust=-1)+
ylim(0,600)+
labs(
title = 'Distribution of Languages by Caller
1 = Amharic, 2=Oromiffa, 3=Tigrigna, 4=Wolayitta, and 5=Sidamigna',
x = 'Language',
y= 'count'
)

#Distribution of time difference bewtween first and last call
lifetime<- log_data %>%
group_by(callerId, caller_lifetime) %>%
count()
ggplot(data=lifetime, aes(x=caller_lifetime)) +
geom_histogram(fill='brown', color='black')+
labs(
title = 'Distribution of Call Lifetimes',
x = 'Years between First and Last Call',
y= 'count'
)

#distribution of calls made
calls_made <- log_data %>%
group_by(callerId, noCallsMade) %>%
count()
ggplot(calls_made, aes(x=noCallsMade)) +
geom_histogram(color="black", fill="blue") +
xlim(0,350) +
labs(
title = 'Distribution of calls made per individual over lifetime (Outliers Excluded) \n
Min. 1st Qu. Median Mean 3rd Qu. Max.
3.0 45.0 69.0 99.9 106.0 7110.0 ',
x = 'Total number of calls'
)

content_listened <- filter(log_data, grepl("CONTENT",logInfo))
content_listened <- filter(content_listened , !grepl("CONTENT MENU",logInfo))
content_listened <- filter(content_listened , !grepl("CONTENT IS NOT AVAILABLE",logInfo))
#Creating a content#_played column
content_listened$content_played <- ifelse(str_detect(content_listened$logInfo, 'CONTENT PLAYED', negate = FALSE),1,0)
content_listened$replay_request <- ifelse(str_detect(content_listened$logInfo, 'CONTENT REPLAY REQUESTED', negate = FALSE),1,0)
content_played<-aggregate(content_listened$content_played,list(content_listened$callerId), FUN=sum)
?rename
content_played <- content_played %>%
dplyr::rename(
con_play = x,
callerId = Group.1
)
content_replay<-aggregate(content_listened$replay_request,list(content_listened$callerId), FUN=sum)
content_replay <- content_replay %>%
dplyr::rename(
con_replay = x,
callerId = Group.1
)
content_counts <- cbind(content_played, content_replay)
content_counts$adjusted_con <- content_counts$con_play-content_counts$con_replay
content_counts$callerId <- NULL
summary(content_counts$adjusted_con)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.00 3.00 8.00 17.79 20.00 279.00
#graphing the true distribution of content played
ggplot(content_counts, aes(x=adjusted_con)) +
geom_histogram(color="black", fill="green") +
xlim(0,100) +
labs(
title = 'Distribution of total Content listened to all Across all Calls (Outliers Excluded) \n
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.00 3.00 8.00 17.79 20.00 279.00 ',
x = 'Total Content Listen Across Calls'
)

# Getting the number of calls per person
calls_made <- log_data %>%
dplyr::group_by(callId) %>%
count()
calls_made_id <- log_data %>%
dplyr::group_by(callId, callerId) %>%
count()
#join between tables
content_ratio <- left_join(calls_made_id, content_counts,by="callerId")
content_ratio[is.na(content_ratio)] <- 0
content_ratio <- content_ratio %>%
dplyr::group_by(callerId, con_play, con_replay, adjusted_con) %>%
count()
content_ratio$ratio <- content_ratio$adjusted_con/content_ratio$n
summary(content_ratio$ratio)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.0000 0.3968 0.8571 1.0800 1.4568 13.4000
ggplot(content_ratio, aes(x=ratio)) +
geom_histogram(color="black", fill="red") +
xlim(0,2)+
labs(
title = 'Distribution of ratio of content listened to Calls (Outliers Excluded) \n
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.0000 0.5614 1.0000 1.2500 1.5292 13.4000 ',
x = 'Content to Call Ratio'
)

sum(content_ratio$n)
[1] 16445
lifetime<- log_data %>%
group_by(callerId, caller_lifetime) %>%
count()
ggplot(data=lifetime, aes(x=caller_lifetime)) +
geom_histogram(fill='#c7d0d8', color='black')+
theme(plot.background = element_rect(fill = "#fcfff9"),
panel.background = element_rect(fill = "#fcfff9"),
panel.grid.major = element_line(size=.1,colour = "black"),
panel.grid.minor = element_line(size=.1,colour = "black"),)+
labs(
title = 'Distribution of Call Lifetimes (2014 - 2020)',
x = 'Years Between First and Last Call',
y= 'Frequency'
)

lang_spoken <- log_data %>%
group_by(callerId, langId) %>%
count()
lang_spoken$langId <- ifelse(lang_spoken$langId == 1, 'AMHARIC', lang_spoken$langId)
lang_spoken$langId <- ifelse(lang_spoken$langId == 2, 'OROMIFFA', lang_spoken$langId)
lang_spoken$langId <- ifelse(lang_spoken$langId == 3, 'TIGRIGNA', lang_spoken$langId)
lang_spoken$langId <- ifelse(lang_spoken$langId == 4, 'WOLAYITTA', lang_spoken$langId)
lang_spoken$langId <- ifelse(lang_spoken$langId == 5, 'SIDAMIGNA', lang_spoken$langId)
#Distribution of languages spoken
ggplot(data=lang_spoken, aes(x=langId)) +
geom_bar(color='black',fill='#19723f')+
ylim(0,600)+
theme(
plot.background = element_rect(fill = "#fcfff9"),
panel.background = element_rect(fill = "#fcfff9"),
panel.grid.major = element_line(size=.1,colour = "black"),
panel.grid.minor = element_line(size=.1,colour = "black"),
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank())+
labs(
title = 'Distribution of Languages by Caller',
x = 'Language',
y= 'Frequency'
)

RAIN MENU/PRE PLANTING MENU/LAND PREPARATION
We continue our pattern of following the most accessed submenu from the previous subment - land preparation! This is also the bottom of a tree. We will breakdown conent selection by language and overall
INCOMING CALL STARTED –> WELCOME MESSAGE PLAYED –> RANDOM EXPERIMENT –>
TOP MENU –> RAIN MENU –> PRE PLANTING MENU –> LAND PREPARATION
LAND PREPARATION
- BARLEY
- MAIZE
- SORGHUM
- TEF
- WHEAT
- SESAME
- FAVA BEAN
- CHICKPEA
- COMMON BEAN
- COTTON
ORDER UNKOWN:
- RICE
- DURAME WHEAT
- LENTIL
- MALT BARLEY
#GETTING THE CROP MENU FROM MENU 1 (rain/preplanting/land preparation sub menu)
land_prep <- filter(log_data, grepl("CONTENT PLAYED - LAND PREPARATION - ",logInfo))
land_prep_final <- land_prep %>%
group_by(callerId, logInfo, langId) %>%
count()
land_prep_final$logInfo<- str_replace(land_prep_final$logInfo, "CONTENT PLAYED - LAND PREPARATION -", "")
ggplot(data=land_prep_final, aes(x=logInfo)) +
theme(axis.text.x = element_text(angle = 45, hjust=2))+
geom_bar()+
labs(
title = 'RAIN MENU/PRE PLANTING/LAND PREPARATION
content actually played by language',
x = 'Content Played',
y= 'count'
)

#get rid of the language breakdown
land_prep_no_lang <- land_prep_final
land_prep_no_lang$logInfo<- str_replace(land_prep_no_lang$logInfo, "- AMHARIC", "")
land_prep_no_lang$logInfo<- str_replace(land_prep_no_lang$logInfo, "- OROMIFFA", "")
land_prep_no_lang$logInfo<- str_replace(land_prep_no_lang$logInfo, "- TIGRIGNA", "")
land_prep_no_lang$logInfo<- str_replace(land_prep_no_lang$logInfo, "- WOLAYITTA", "")
land_prep_no_lang$logInfo<- str_replace(land_prep_no_lang$logInfo, "- WOLAYTIGNA", "")
land_prep_no_lang$logInfo<- str_replace(land_prep_no_lang$logInfo, "- SIDAMIGNA", "")
ggplot(land_prep_no_lang, aes(x=logInfo)) +
theme(axis.text.x = element_text(angle = 90))+
geom_bar()+
labs(
title = 'RAIN MENU/PRE PLANTING/LAND PREPARATION
content played overall',
x = 'Content Played',
y= 'count'
)

ggplot(land_prep_no_lang, aes(langId, fill = logInfo)) +
geom_bar()+
labs(
title = 'ALTERNATIVE RAIN MENU/PRE PLANTING/LAND PREPARATION
content actually played by language
1 = Amharic, 2=Oromiffa, 3=Tigrigna, 4=Wolayitta, and 5=Sidamigna
',
x = 'Language'
)

BIG TAKEAWAY: 35% of users end up accessing the maize menu at some point! Wheat, Tef, Sorghum, and Barley also appear to be qualitatively significant
There is no menu to go deeper in, so let’s go back up a level and check to see if other branches have a lot of access
LS0tCnRpdGxlOiAiUEFELUFUQSBDYWxsIExvZyBBbmFseXNpcyIKb3V0cHV0OgogIHdvcmRfZG9jdW1lbnQ6IGRlZmF1bHQKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQoKIyMjIyBMaWJyYXJpZXMgdXNlZCBpbiB0aGUgUHJvamVjdCBhbmQgdXBsb2FkaW5nIGRhdGEKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShkcGx5cikKbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KHN2TWlzYykKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGd0YWJsZSkKbGlicmFyeSgiZ2dwdWJyIikKCmxvZ19kYXRhIDwtIHJlYWRfY3N2KCJ+L0Rlc2t0b3AvUEFFL2dpdGh1Yi9kYXRhL2xvZ0RhdGEuY3N2IikKI2xvZ19kYXRhIDwtIHJlYWRfY3N2KCJ+L0Rlc2t0b3AvUEFFL2dpdGh1Yi9kYXRhL2JlbkRhdGFfd2Vha0NhbGxlcnMuY3N2IikKCmxvZ19kYXRhX3NhdmVyIDwtIGxvZ19kYXRhCgpsb2dfZGF0YSA8LSB1bmlxdWUobG9nX2RhdGEpCgpsb2dfZGF0YSRsb2dJbmZvIDwtIHN0cl9yZXBsYWNlKGxvZ19kYXRhJGxvZ0luZm8sICIgICIsICIgIikKCiNNQUtFIElUIEFMTCBVUFBFUiEhIQoKbG9nX2RhdGEkbG9nSW5mbyA8LSB0b3VwcGVyKGxvZ19kYXRhJGxvZ0luZm8pCgojIyMgR0VUVElORyBUSEUgREFURSBNT05USCBBTkQgWUVBUiBJRiBJIFdBTlQhISEKZXh0cmFjdGRhdGUgPC0gZnVuY3Rpb24oZGF0ZSkgewogICAgZGF5IDwtIGZvcm1hdChkYXRlLCBmb3JtYXQ9IiVkIikKICAgIG1vbnRoIDwtIGZvcm1hdChkYXRlLCBmb3JtYXQ9IiVtIikKICAgIHllYXIgPC0gZm9ybWF0KGRhdGUsIGZvcm1hdD0iJVkiKQoKICAgIGNiaW5kKGRheSwgbW9udGgsIHllYXIpCn0KCiNtYWtpbmcgZmlyc3QgY2FsbHMKZmlyc3RfY2FsbDwtZXh0cmFjdGRhdGUobG9nX2RhdGEkY2FsbFRpbWUpCgoKI21ha2luZyBsYXN0IGNhbGwKbGFzdF9kYXkgPC1zdWJzdHIobG9nX2RhdGEkZXZlbnRUaW1lLCA5LCAxMCkKbGFzdF9tb250aCA8LSBzdWJzdHIobG9nX2RhdGEkZXZlbnRUaW1lLCA2LCA3KQpsYXN0X3llYXIgPC1zdWJzdHIobG9nX2RhdGEkZXZlbnRUaW1lLCAxLCA0KQoKbG9nX2RhdGE8LWNiaW5kKGxvZ19kYXRhLCBmaXJzdF9jYWxsLGxhc3RfZGF5LGxhc3RfbW9udGgsbGFzdF95ZWFyKQoKI0NvbnZlcnRpbmcgY29sdW1ucyB0byBudW1lcmljCmxvZ19kYXRhJGRheSA8LWFzLm51bWVyaWMobG9nX2RhdGEkZGF5KQpsb2dfZGF0YSRsYXN0X2RheSA8LSBhcy5udW1lcmljKGxvZ19kYXRhJGxhc3RfZGF5KQpsb2dfZGF0YSRtb250aCA8LWFzLm51bWVyaWMobG9nX2RhdGEkbW9udGgpCmxvZ19kYXRhJGxhc3RfbW9udGggPC0gYXMubnVtZXJpYyhsb2dfZGF0YSRsYXN0X21vbnRoKQpsb2dfZGF0YSR5ZWFyIDwtIGFzLm51bWVyaWMobG9nX2RhdGEkeWVhcikKbG9nX2RhdGEkbGFzdF95ZWFyIDwtIGFzLm51bWVyaWMobG9nX2RhdGEkbGFzdF95ZWFyICkKCgpsb2dfZGF0YSR5ZWFyIDwtIGxvZ19kYXRhJHllYXIgK2xvZ19kYXRhJG1vbnRoLzEyCmxvZ19kYXRhJGxhc3RfeWVhciA8LSBsb2dfZGF0YSRsYXN0X3llYXIgKyBsb2dfZGF0YSRsYXN0X21vbnRoLzEyCgpsb2dfZGF0YSRjYWxsZXJfbGlmZXRpbWUgPC0gbG9nX2RhdGEkbGFzdF95ZWFyIC0gbG9nX2RhdGEkeWVhcgpgYGAKCipDbWQrT3B0aW9uK0kqLgoKICpDbWQrU2hpZnQrSyogCiAKIyMjIFBSRUxJTUlOQVJZIERJU1RSSUJVVElPTlMKIAoqKkluIHRoaXMgc2VjdGlvbiwgd2UgZGlzcGxheSBzb21lIG9mIHRoZSBiYXNpYyBkaXN0cmlidXRpb25zIG9mIHRoZSBkYXRhIGluY2x1ZGluZyBsYW5ndWFnZXMsIHRvdGFsIGxpZmVldGltZSBvZiBhIGdpdmVuIGNhbGxlciwgY29sbHMgbWFkZSwgY29udGVudCBhY2Nlc3NlZCwgYW5kIHRoZSByYXRpbyBvZiBjb250ZW50IGxpc3RlbmVkIHRvIGNhbGxzIG1hZGUuKioKCioqQmFzZWQgb24gdGhlIGdyYXBocyBiZWxvdywgd2UgYXJlIG5lcnZvdXMgdGhhdCBzb21lIG9mIHRoZSBkYXRhIGlzIG5vdCByYW5kb20gZ2l2ZW4gdGhlIGluY3JlZGlibHkgaGlnaCByYXRpbyBmb3IgY29udGVudCBsaXN0ZW5lZCB0byBjYWxscyBtYWRlLCBidXQgZ2l2ZW4gdGhhdCB0aGUgZGF0YSBpcyBkaXN0cmlidXRlZCBmYWlybHkgZXZlbmx5IGFjcm9zcyB0aGVlIGRpZmZlcmVudCBncmFwaHMsIHdlIGFyZSB1bnN1cmUqKgoKYGBge3J9Cmxhbmdfc3Bva2VuIDwtIGxvZ19kYXRhICU+JQogIGdyb3VwX2J5KGNhbGxlcklkLCBsYW5nSWQpICU+JQogIGNvdW50KCkKCiNEaXN0cmlidXRpb24gb2YgbGFuZ3VhZ2VzIHNwb2tlbgpnZ3Bsb3QoZGF0YT1sYW5nX3Nwb2tlbiwgYWVzKHg9bGFuZ0lkKSkgKwogIGdlb21fYmFyKGZpbGw9J3JlZCcpKwogIHlsaW0oMCw2MDApKwogIGxhYnMoCiAgICB0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgTGFuZ3VhZ2VzIGJ5IENhbGxlcgogICAgMSA9IEFtaGFyaWMsIDI9T3JvbWlmZmEsIDM9VGlncmlnbmEsIDQ9V29sYXlpdHRhLCBhbmQgNT1TaWRhbWlnbmEnLAogICAgeCA9ICdMYW5ndWFnZScsCiAgICB5PSAnY291bnQnCiAgKQoKCiNEaXN0cmlidXRpb24gb2YgdGltZSBkaWZmZXJlbmNlIGJld3R3ZWVuIGZpcnN0IGFuZCBsYXN0IGNhbGwKCmxpZmV0aW1lPC0gbG9nX2RhdGEgJT4lCiAgZ3JvdXBfYnkoY2FsbGVySWQsIGNhbGxlcl9saWZldGltZSkgJT4lCiAgY291bnQoKQoKZ2dwbG90KGRhdGE9bGlmZXRpbWUsIGFlcyh4PWNhbGxlcl9saWZldGltZSkpICsKICBnZW9tX2hpc3RvZ3JhbShmaWxsPSdicm93bicsIGNvbG9yPSdibGFjaycpKwogIGxhYnMoCiAgICB0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgQ2FsbCBMaWZldGltZXMnLAogICAgeCA9ICdZZWFycyBiZXR3ZWVuIEZpcnN0IGFuZCBMYXN0IENhbGwnLAogICAgeT0gJ2NvdW50JwogICkKCiNkaXN0cmlidXRpb24gb2YgY2FsbHMgbWFkZQoKY2FsbHNfbWFkZSA8LSBsb2dfZGF0YSAlPiUKICBncm91cF9ieShjYWxsZXJJZCwgbm9DYWxsc01hZGUpICU+JQogIGNvdW50KCkKCmdncGxvdChjYWxsc19tYWRlLCBhZXMoeD1ub0NhbGxzTWFkZSkpICsKICBnZW9tX2hpc3RvZ3JhbShjb2xvcj0iYmxhY2siLCBmaWxsPSJibHVlIikgKwogIHhsaW0oMCwzNTApICsKICBsYWJzKAogICAgdGl0bGUgPSAnRGlzdHJpYnV0aW9uIG9mIGNhbGxzIG1hZGUgcGVyIGluZGl2aWR1YWwgb3ZlciBsaWZldGltZSAoT3V0bGllcnMgRXhjbHVkZWQpIFxuCk1pbi4gMXN0IFF1LiAgTWVkaWFuICBNZWFuICAgM3JkIFF1LiAgICBNYXguIAogICAgMy4wICAgIDQ1LjAgICAgNjkuMCAgICAgOTkuOSAgICAxMDYuMCAgICA3MTEwLjAgJywKICAgIHggPSAnVG90YWwgbnVtYmVyIG9mIGNhbGxzJwogICkKCmNvbnRlbnRfbGlzdGVuZWQgPC0gZmlsdGVyKGxvZ19kYXRhLCBncmVwbCgiQ09OVEVOVCIsbG9nSW5mbykpCmNvbnRlbnRfbGlzdGVuZWQgPC0gZmlsdGVyKGNvbnRlbnRfbGlzdGVuZWQgLCAhZ3JlcGwoIkNPTlRFTlQgTUVOVSIsbG9nSW5mbykpCmNvbnRlbnRfbGlzdGVuZWQgPC0gZmlsdGVyKGNvbnRlbnRfbGlzdGVuZWQgLCAhZ3JlcGwoIkNPTlRFTlQgSVMgTk9UIEFWQUlMQUJMRSIsbG9nSW5mbykpCgojQ3JlYXRpbmcgYSBjb250ZW50I19wbGF5ZWQgY29sdW1uCmNvbnRlbnRfbGlzdGVuZWQkY29udGVudF9wbGF5ZWQgPC0gaWZlbHNlKHN0cl9kZXRlY3QoY29udGVudF9saXN0ZW5lZCRsb2dJbmZvLCAnQ09OVEVOVCBQTEFZRUQnLCBuZWdhdGUgPSBGQUxTRSksMSwwKQpjb250ZW50X2xpc3RlbmVkJHJlcGxheV9yZXF1ZXN0IDwtIGlmZWxzZShzdHJfZGV0ZWN0KGNvbnRlbnRfbGlzdGVuZWQkbG9nSW5mbywgJ0NPTlRFTlQgUkVQTEFZIFJFUVVFU1RFRCcsIG5lZ2F0ZSA9IEZBTFNFKSwxLDApCgpjb250ZW50X3BsYXllZDwtYWdncmVnYXRlKGNvbnRlbnRfbGlzdGVuZWQkY29udGVudF9wbGF5ZWQsbGlzdChjb250ZW50X2xpc3RlbmVkJGNhbGxlcklkKSwgRlVOPXN1bSkKP3JlbmFtZQpjb250ZW50X3BsYXllZCA8LSBjb250ZW50X3BsYXllZCAlPiUgCiAgZHBseXI6OnJlbmFtZSgKICAgIGNvbl9wbGF5ID0geCwKICAgIGNhbGxlcklkID0gR3JvdXAuMQogICAgKQoKY29udGVudF9yZXBsYXk8LWFnZ3JlZ2F0ZShjb250ZW50X2xpc3RlbmVkJHJlcGxheV9yZXF1ZXN0LGxpc3QoY29udGVudF9saXN0ZW5lZCRjYWxsZXJJZCksIEZVTj1zdW0pCmNvbnRlbnRfcmVwbGF5IDwtIGNvbnRlbnRfcmVwbGF5ICU+JSAKIGRwbHlyOjpyZW5hbWUoCiAgICBjb25fcmVwbGF5ID0geCwKICAgIGNhbGxlcklkID0gR3JvdXAuMQogICAgKQoKY29udGVudF9jb3VudHMgPC0gY2JpbmQoY29udGVudF9wbGF5ZWQsIGNvbnRlbnRfcmVwbGF5KQoKY29udGVudF9jb3VudHMkYWRqdXN0ZWRfY29uIDwtIGNvbnRlbnRfY291bnRzJGNvbl9wbGF5LWNvbnRlbnRfY291bnRzJGNvbl9yZXBsYXkKCmNvbnRlbnRfY291bnRzJGNhbGxlcklkIDwtIE5VTEwKCnN1bW1hcnkoY29udGVudF9jb3VudHMkYWRqdXN0ZWRfY29uKQoKCiNncmFwaGluZyB0aGUgdHJ1ZSBkaXN0cmlidXRpb24gb2YgY29udGVudCBwbGF5ZWQKZ2dwbG90KGNvbnRlbnRfY291bnRzLCBhZXMoeD1hZGp1c3RlZF9jb24pKSArCiAgZ2VvbV9oaXN0b2dyYW0oY29sb3I9ImJsYWNrIiwgZmlsbD0iZ3JlZW4iKSArCiAgeGxpbSgwLDEwMCkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgdG90YWwgQ29udGVudCBsaXN0ZW5lZCB0byBhbGwgQWNyb3NzIGFsbCBDYWxscyAoT3V0bGllcnMgRXhjbHVkZWQpIFxuCiAgICAgIE1pbi4gMXN0IFF1LiAgTWVkaWFuICAgIE1lYW4gM3JkIFF1LiAgICBNYXguIAogICAwLjAwICAgIDMuMDAgICAgOC4wMCAgIDE3Ljc5ICAgMjAuMDAgIDI3OS4wMCAnLAogICAgeCA9ICdUb3RhbCBDb250ZW50IExpc3RlbiBBY3Jvc3MgQ2FsbHMnCiAgKQoKCiMgR2V0dGluZyB0aGUgbnVtYmVyIG9mIGNhbGxzIHBlciBwZXJzb24KY2FsbHNfbWFkZSA8LSBsb2dfZGF0YSAlPiUKICBkcGx5cjo6Z3JvdXBfYnkoY2FsbElkKSAlPiUKICBjb3VudCgpCgpjYWxsc19tYWRlX2lkIDwtIGxvZ19kYXRhICU+JQogIGRwbHlyOjpncm91cF9ieShjYWxsSWQsIGNhbGxlcklkKSAlPiUKICBjb3VudCgpCgoKI2pvaW4gYmV0d2VlbiB0YWJsZXMKY29udGVudF9yYXRpbyA8LSBsZWZ0X2pvaW4oY2FsbHNfbWFkZV9pZCwgY29udGVudF9jb3VudHMsYnk9ImNhbGxlcklkIikKY29udGVudF9yYXRpb1tpcy5uYShjb250ZW50X3JhdGlvKV0gPC0gMAoKY29udGVudF9yYXRpbyA8LSBjb250ZW50X3JhdGlvICU+JQogIGRwbHlyOjpncm91cF9ieShjYWxsZXJJZCwgY29uX3BsYXksIGNvbl9yZXBsYXksIGFkanVzdGVkX2NvbikgJT4lCiAgY291bnQoKQoKY29udGVudF9yYXRpbyRyYXRpbyA8LSBjb250ZW50X3JhdGlvJGFkanVzdGVkX2Nvbi9jb250ZW50X3JhdGlvJG4KCnN1bW1hcnkoY29udGVudF9yYXRpbyRyYXRpbykKCmdncGxvdChjb250ZW50X3JhdGlvLCBhZXMoeD1yYXRpbykpICsKICBnZW9tX2hpc3RvZ3JhbShjb2xvcj0iYmxhY2siLCBmaWxsPSJyZWQiKSArCiAgeGxpbSgwLDIpKwogIGxhYnMoCiAgICB0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgcmF0aW8gb2YgY29udGVudCBsaXN0ZW5lZCB0byBDYWxscyAoT3V0bGllcnMgRXhjbHVkZWQpIFxuCk1pbi4gMXN0IFF1LiAgTWVkaWFuICAgIE1lYW4gM3JkIFF1LiAgICBNYXguICAgICAKIDAuMDAwMCAgMC41NjE0ICAxLjAwMDAgIDEuMjUwMCAgMS41MjkyIDEzLjQwMDAgJywKICAgIHggPSAnQ29udGVudCB0byBDYWxsIFJhdGlvJwogICkKCgpzdW0oY29udGVudF9yYXRpbyRuKQpgYGAKYGBge3J9CmxpZmV0aW1lPC0gbG9nX2RhdGEgJT4lCiAgZ3JvdXBfYnkoY2FsbGVySWQsIGNhbGxlcl9saWZldGltZSkgJT4lCiAgY291bnQoKQoKZ2dwbG90KGRhdGE9bGlmZXRpbWUsIGFlcyh4PWNhbGxlcl9saWZldGltZSkpICsKICBnZW9tX2hpc3RvZ3JhbShmaWxsPScjYzdkMGQ4JywgY29sb3I9J2JsYWNrJykrCiAgdGhlbWUocGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI2ZjZmZmOSIpLAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZmNmZmY5IiksCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplPS4xLGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUoc2l6ZT0uMSxjb2xvdXIgPSAiYmxhY2siKSwpKwogIGxhYnMoCiAgICB0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgQ2FsbCBMaWZldGltZXMgKDIwMTQgLSAyMDIwKScsCiAgICB4ID0gJ1llYXJzIEJldHdlZW4gRmlyc3QgYW5kIExhc3QgQ2FsbCcsCiAgICB5PSAnRnJlcXVlbmN5JwogICkKCmxhbmdfc3Bva2VuIDwtIGxvZ19kYXRhICU+JQogIGdyb3VwX2J5KGNhbGxlcklkLCBsYW5nSWQpICU+JQogIGNvdW50KCkKCmxhbmdfc3Bva2VuJGxhbmdJZCA8LSBpZmVsc2UobGFuZ19zcG9rZW4kbGFuZ0lkID09IDEsICdBTUhBUklDJywgbGFuZ19zcG9rZW4kbGFuZ0lkKQpsYW5nX3Nwb2tlbiRsYW5nSWQgPC0gaWZlbHNlKGxhbmdfc3Bva2VuJGxhbmdJZCA9PSAyLCAnT1JPTUlGRkEnLCBsYW5nX3Nwb2tlbiRsYW5nSWQpCmxhbmdfc3Bva2VuJGxhbmdJZCA8LSBpZmVsc2UobGFuZ19zcG9rZW4kbGFuZ0lkID09IDMsICdUSUdSSUdOQScsIGxhbmdfc3Bva2VuJGxhbmdJZCkKbGFuZ19zcG9rZW4kbGFuZ0lkIDwtIGlmZWxzZShsYW5nX3Nwb2tlbiRsYW5nSWQgPT0gNCwgJ1dPTEFZSVRUQScsIGxhbmdfc3Bva2VuJGxhbmdJZCkKbGFuZ19zcG9rZW4kbGFuZ0lkIDwtIGlmZWxzZShsYW5nX3Nwb2tlbiRsYW5nSWQgPT0gNSwgJ1NJREFNSUdOQScsIGxhbmdfc3Bva2VuJGxhbmdJZCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKI0Rpc3RyaWJ1dGlvbiBvZiBsYW5ndWFnZXMgc3Bva2VuCmdncGxvdChkYXRhPWxhbmdfc3Bva2VuLCBhZXMoeD1sYW5nSWQpKSArCiAgZ2VvbV9iYXIoY29sb3I9J2JsYWNrJyxmaWxsPScjMTk3MjNmJykrCiAgeWxpbSgwLDYwMCkrCiAgICB0aGVtZSgKICAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI2ZjZmZmOSIpLAogICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZmNmZmY5IiksCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplPS4xLGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUoc2l6ZT0uMSxjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSkrCiAgbGFicygKICAgIHRpdGxlID0gJ0Rpc3RyaWJ1dGlvbiBvZiBMYW5ndWFnZXMgYnkgQ2FsbGVyJywKICAgIHggPSAnTGFuZ3VhZ2UnLAogICAgeT0gJ0ZyZXF1ZW5jeScKICApCmBgYAoKIyMjIFRPUCBNRU5VCgoqKk5leHQsIHdlIHdhbnQgdG8gQnJlYWtkIGRvd24gdGhlIGluaXRpYWwgTWVudSBvcHRpb25zIGFuZCBkZWx2ZSBpbnRvIHRoZSBkaXN0cmlidXRpb25zIG9mIHRoZSBzZWxlY3Rpb25zIHRoYXQgdGhlIGZhcm1lciBjYW4gbWFrZSBhdCBhIGRpZmZlcmVudCBzdGF0ZSBpbiB0aGUgSVZSIFN5c3RlbSoqCgoqKkZvciB0aGUgZmlyc3QgYW5hbHlzaXMsIHdlIGxvb2tlZCBhdCB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBUT1AgTUVOVSBpbiB0aGUgZGF0YS4gVGhpcyBjb21lcyBpbiBhcyBmb2xsb3dzKio6CgojIyMjIyBJTkNPTUlORyBDQUxMIFNUQVJURUQgLS0+IFdFTENPTUUgTUVTU0FHRSBQTEFZRUQgLS0+IEFTU0lOR0VEIFRPIEVYUEVSSU1FTlQgKE9QVElPTkFMKSAtLT4gVE9QIE1FTlUKCioqVE9QIE1FTlUqKgoKIC0gUkFJTiBPUFRJT04KIC0gSEhJIE9QVElPTiAoaG91c2Vob2xkIElycmlnYXRpb24pCiAtIFJFU0VUIFBST0ZJTEUgT1BUSU9OCiAtIFRPUCBNRU5VIFJFUExBWQogLSBMSVZFU1RPQ0sgT1BUSU9OIAogLSBDT1ZJRCBPUFRJT04KIAogKlBsZWFzZSBub3RlLCB3ZSBhcmUgdW5zdXJlIG9mIHRoZSBvcmRlciB0aGVzZSBhcmUgcHJlc2VudGVkLiBGb3Igb3RoZXIgbWVudXMsIHdlIGRvIGhhdmUgdGhlIG9yZGVyKgogCiAqKkJlbG93LCB3ZSBoYXZlIHZpc3VhbGl6ZWQgdGhlIG51bWJlciBvZiBmYXJtZXJzLCBvdXQgb2Ygb3VyIHNhbXBsZSwgdGhhdCBpbiB0aGUgbGlmZSB0aW1lIG9mIHRoZWlyIGNhbGxpbmcgaGlzdG9yeSBoYXZlIGFjY2Vzc2VkIGEgZ2l2ZW4gVE9QIE1FTlUgaXRlbSBhdCBsZWFzdCBvbmNlKioKIAogKipBZGRpdGlvbmFsbHksIHdlIGFsc28gdmlzdWFsaXplZCB0aGlzIHNhbWUgc2VsZWN0aW9uIGRpdmlkZWQgYnkgbGFuZ3VhZ2UgdG8gc2VlIGlmIHRoZSBwYXR0ZXJucyBvZiBzZWxlY2lvbnQgYXJlIHNpbWlsYXIgb3IgZGlmZmVyZW50IGFjcm9zcyBsYW5nYXVnZXMqKnYKIApgYGB7cn0KI1NUQVJUSU5HIEhFUkUgSVMgRk9SIFVOSVFVRSBDQUxMRVJTCiMgZmlsdGVyaW5nIG91dCB0b3AgTWVudSBrZXlzCgp0b3BfbWVudSA8LWZpbHRlcihsb2dfZGF0YSwgZ3JlcGwoIlRPUCBNRU5VIixsb2dJbmZvKSkKCiNjbGVhbmluZyB0aGUgYXhpcwp0b3BfbWVudSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UodG9wX21lbnUkbG9nSW5mbywgIlRPUCBNRU5VIC0gIiwgIiIpCnRvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZSh0b3BfbWVudSRsb2dJbmZvLCAiIFBSRVNTRUQiLCAiIikKdG9wX21lbnUkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHRvcF9tZW51JGxvZ0luZm8sICIgUFJFU1NFRCIsICIiKQp0b3BfbWVudSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UodG9wX21lbnUkbG9nSW5mbywgIiBTRUxFQ1RFRCIsICIiKQoKdG9wX21lbnUgPC0gdG9wX21lbnUgJT4lCiAgZ3JvdXBfYnkoY2FsbGVySWQsIGxvZ0luZm8sIGxhbmdJZCkgJT4lCiAgY291bnQoKQoKCmdncGxvdCh0b3BfbWVudSwgYWVzKGxvZ0luZm8pKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPTEpKSsKICBnZW9tX2JhcigpKwogIGxhYnMoCiAgICB0aXRsZSA9ICdEaXN0aXJ1dGlvbiBvZiBUT1AgTUVOVSBpdGVtcyBzZWxlY3RlZCBhdCBsZWFzdCBvbmNlIGJ5IGEgdW5pcXVlIGNhbGxlcicsCiAgICB4ID0gJ1RPUCBNRU5VIG9wdGlvbnMnCiAgKQoKZ2dwbG90KHRvcF9tZW51LCBhZXMobGFuZ0lkLCBmaWxsID0gbG9nSW5mbykpICsKICBnZW9tX2JhcigpKwogIGxhYnMoCiAgICB0aXRsZSA9ICdEaXN0aXJ1dGlvbiBvZiBMYW5ndWFnZXMgZGl2aWRlZCBieSBUT1AgTUVOVSBvcHRpb24KICAgIDEgPSBBbWhhcmljLCAyPU9yb21pZmZhLCAzPVRpZ3JpZ25hLCA0PVdvbGF5aXR0YSwgYW5kIDU9U2lkYW1pZ25hJywKICAgIHggPSAnTGFuZ3VhZ2UnCiAgKQoKI1NUQVJUSU5HIEhFUkUgSVMgRk9SIFVOSVFVRSBDQUxMUwoKdG9wX21lbnVfY2FsbCA8LWZpbHRlcihsb2dfZGF0YSwgZ3JlcGwoIlRPUCBNRU5VIixsb2dJbmZvKSkKCiNjbGVhbmluZyB0aGUgYXhpcwp0b3BfbWVudV9jYWxsJGxvZ0luZm88LSBzdHJfcmVwbGFjZSh0b3BfbWVudV9jYWxsJGxvZ0luZm8sICJUT1AgTUVOVSAtICIsICIiKQp0b3BfbWVudV9jYWxsJGxvZ0luZm88LSBzdHJfcmVwbGFjZSh0b3BfbWVudV9jYWxsJGxvZ0luZm8sICIgUFJFU1NFRCIsICIiKQp0b3BfbWVudV9jYWxsJGxvZ0luZm88LSBzdHJfcmVwbGFjZSh0b3BfbWVudV9jYWxsJGxvZ0luZm8sICIgUFJFU1NFRCIsICIiKQp0b3BfbWVudV9jYWxsJGxvZ0luZm88LSBzdHJfcmVwbGFjZSh0b3BfbWVudV9jYWxsJGxvZ0luZm8sICIgU0VMRUNURUQiLCAiIikKCnRvcF9tZW51X2NhbGwkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHRvcF9tZW51X2NhbGwkbG9nSW5mbywgIlJBSU4gT1BUSU9OIiwgIlJBSU4iKQp0b3BfbWVudV9jYWxsJGxvZ0luZm88LSBzdHJfcmVwbGFjZSh0b3BfbWVudV9jYWxsJGxvZ0luZm8sICJISEkgT1BUSU9OIiwgIkhISSIpCnRvcF9tZW51X2NhbGwkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHRvcF9tZW51X2NhbGwkbG9nSW5mbywgIkxJVkVTVE9DSyBPUFRJT04iLCAiTElWRVNUT0NLIikKdG9wX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UodG9wX21lbnVfY2FsbCRsb2dJbmZvLCAiQ09WSUQgT1BUSU9OIiwgIkNPVklEIikKdG9wX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UodG9wX21lbnVfY2FsbCRsb2dJbmZvLCAiUkVTRVQgUFJPRklMRSBPUFRJT04iLCAiTk9OLU5VTUVSSUMgS0VZIikKdG9wX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UodG9wX21lbnVfY2FsbCRsb2dJbmZvLCAiVE9QIE1FTlUgUkVQTEFZRUQiLCAiTk9OLU5VTUVSSUMgS0VZIikKdG9wX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UodG9wX21lbnVfY2FsbCRsb2dJbmZvLCAiVE9QIE1FTlUgSU5WQUxJRCBLRVkiLCAiTk9OLU5VTUVSSUMgS0VZIikKCnRvcF9tZW51X2NhbGwgPC0gdG9wX21lbnVfY2FsbCAlPiUKICBncm91cF9ieShjYWxsSWQsIGxvZ0luZm8pICU+JQogIGNvdW50KCkKCnRvcF9tZW51X2NhbGw8LSB0b3BfbWVudV9jYWxsW21hdGNoKHVuaXF1ZSh0b3BfbWVudV9jYWxsJGNhbGxJZCksIHRvcF9tZW51X2NhbGwkY2FsbElkKSxdCgpnZ3Bsb3QodG9wX21lbnVfY2FsbCwgYWVzKHg9ZmN0X2luZnJlcShsb2dJbmZvKSkpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwLCBoanVzdCA9MSkpKwogIGdlb21fYmFyKGNvbG9yPSdibGFjaycsIGZpbGw9JyMxOTcyM2YnKSsKICBnZW9tX3RleHQoc3RhdD0nY291bnQnLCBhZXMobGFiZWw9Li5jb3VudC4uKSwgdmp1c3Q9LTEpKwogIGdlb21fdGV4dChhZXMoeD0nUkFJTicsIHk9MjAwLCBsYWJlbD0nUHJlc3MgMScpLGNvbG9yPScjZmNmZmY5JykrCiAgZ2VvbV90ZXh0KGFlcyh4PSdISEknLCB5PTIwMCwgbGFiZWw9J1ByZXNzIDInKSxjb2xvcj0nI2ZjZmZmOScpKwogIGdlb21fdGV4dChhZXMoeD0nTElWRVNUT0NLJywgeT0yMDAsIGxhYmVsPSdQcmVzcyAzJyksY29sb3I9JyNmY2ZmZjknKSsKICBnZW9tX3RleHQoYWVzKHg9J0NPVklEJywgeT03NTAsIGxhYmVsPSdQcmVzcyA0JykscG9zaXRpb24gPSBwb3NpdGlvbl9udWRnZSh4PS4zKSxjb2xvcj0nYmxhY2snKSsKICBnZW9tX3RleHQoYWVzKHg9J05PTi1OVU1FUklDIEtFWScsIHk9MjAwLCBsYWJlbD0nUHJlc3MgIy8qJyksY29sb3I9JyNmY2ZmZjknKSsKICB5bGltKDAsNTAwMCkrCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3QgPTEpLAogICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZmNmZmY5IiksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNmY2ZmZjkiKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKHNpemU9LjEsY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShzaXplPS4xLGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpKSsKICBsYWJzKAogICAgdGl0bGUgPSAnRGlzdHJpYnV0aW9uIG9mIE9wdGlvbnMgU2VsZWN0ZWQnLAogICAgeCA9ICdUb3AgTWVudSBPcHRpb25zJywKICAgIHk9J0ZyZXF1ZW5jeScKICApCgpgYGAKIAogCiAKKipBcyB3ZSBjYW4gZWFzaWx5IHNlZSwgdGhlIFJBSU4gb3B0aW9ucyBhbmQgdGhlIEhISSBvcHRpb24gZG9taW5hdGUgdGhlIGNob2ljZXMgZnJvbSB0aGUgdG9wIE1lbnUuIFNvLCB3ZSBkZWNpZGVkIHRvIGRpdmUgZGVlcGVyIGludG8gZWFjaCBvZiB0aGVzZSBtZW51cyB0byBzZWUgaWYgdGhlcmUgYXJlIGFueSBvdXRsaWVyIHNlbGVjdGlvbnMgdGhhdCBhcmUgZGVlcCB3aXRoaW4gdGhlIHN5c3RlbS4gQWRkaXRpb25hbGx5LCB0aHMgZGlzdHJpYnV0aW9uIGFjcm9zcyBsYW5ndWFnZXMgc2VlbXMgdG8gYmUgZmFpcmx5IGNvbnNpc3RlbnQgYXQgZmFjZSB2YWx1ZS4gV2UgY2FuIHJ1biB0ZXN0cyBpbiB0aGUgZnV0dXJlLCBidXQgZm9yIEVEQSB0aGlzIHdpbGwgYmUgYWRlcXVhdGUuIEZvciAzLzQgbGFuZ2F1Z2Ugb3B0aW9ucyAtIGhhdmluZyBtb3JlIGRhdGEgd291bGQgYmUgYXBwcmVjYWl0ZWQqKgoKCiMjIyBSQUlOIE1FTlUKCiMjIyMjIElOQ09NSU5HIENBTEwgU1RBUlRFRCAtLT4gV0VMQ09NRSBNRVNTQUdFIFBMQVlFRCAtLT4gUkFORE9NIEVYUEVSSU1FTlQgLS0+IFRPUCBNRU5VIC0tPiBSQUlOIE1FTlUKCioqSGVyZSwgd2UgbG9vayBhdCB0aGUgYnJlYWtkb3duIG9mIGluZGl2aWR1YWxzIHdobyBoYXZlIHNlbGVjdGVkIGEgZ2l2ZW4gb3B0aW9uIGluIHRoZSByYWluIG1lbnUgYXQgbGVhc3Qgb25jZS4gSW4gdGhlIGRhdGEsIE1BSU4gTUVOVSA9PSBSQUlOIE1FTlUuKioKCgoqKlJBSU4gTUVOVSoqCgogLSBQUkUgUExBTlRJTkcgT1BUSU9OCiAtIFBMQU5USU5HIE9QVElPTgogLSBDUk9QIFBST1RFQ1RJT04gT1BUSU9OCiAtIEZFUlRJTElaR0VSIFNJREUgRFJFRVNTSU5HCiAtIFBPU1QgSEFSVkVTVCBBTkQgUFJPQ0VTU0lORwogLSBSRVBFQVQgUkFJTiBNRU5VCiAtIFJFVFVSTiBUTyBUT1AgTUVOVQogLSBJTlZBTElEIEtFWSBQUkVTU0VEIChBRERJVElPTkFMIE9VVENPTUUpCgoKCmBgYHtyfQojIFB1bGxpbmcgb3V0IHRoZSByYWluIE1lbnUgQnkgQ0FMTExFUgoKI1JBSU4gPT0gSEhJX1JBSU4KcmFpbl9tZW51IDwtIGZpbHRlcihsb2dfZGF0YSwgZ3JlcGwoIk1BSU4gTUVOVSAtICIsbG9nSW5mbykpCnJhaW5fbWVudSA8LSBmaWx0ZXIocmFpbl9tZW51LCAhZ3JlcGwoIkxJVkVTVE9DSyBNQUlOIE1FTlUiLGxvZ0luZm8pKQpyYWluX21lbnUgPC0gZmlsdGVyKHJhaW5fbWVudSwgIWdyZXBsKCJISEkgTUFJTiBNRU5VIixsb2dJbmZvKSkKcmFpbl9tZW51IDwtIGZpbHRlcihyYWluX21lbnUsICFncmVwbCgiQ09WSUQtMTkgTUFJTiBNRU5VIixsb2dJbmZvKSkKCiNncm91cGluZyB0aGUgb2JzZXJ2YXRpb25zCnJhaW5fbWVudSA8LXJhaW5fbWVudSAlPiUKICBncm91cF9ieShjYWxsZXJJZCwgbG9nSW5mbywgbGFuZ0lkKSAlPiUKICBjb3VudCgpCgpyYWluX21lbnUkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHJhaW5fbWVudSRsb2dJbmZvLCAiTUFJTiBNRU5VIC0gIiwgIiIpCnJhaW5fbWVudSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UocmFpbl9tZW51JGxvZ0luZm8sICIgU0VMRUNURUQiLCAiIikKcmFpbl9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX21lbnUkbG9nSW5mbywgIiBQUkVTU0VEIiwgIiIpCnJhaW5fbWVudSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UocmFpbl9tZW51JGxvZ0luZm8sICIgT1BUSU9OIiwgIiIpCgojcGxvdHRpbmcgcmFpbiBtZW51IGJyZWFrZG93bgojIGdncGxvdChkYXRhPXJhaW5fbWVudSwgYWVzKHg9bG9nSW5mbykpICsKIyAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0xKSkrCiMgICBnZW9tX2JhcihmaWxsPSdibHVlJykrCiMgICBsYWJzKAojICAgICB0aXRsZSA9ICdCcmVha2Rvd24gZm9yIEluZGl2aWR1YWxzIEJ5IENvbnRlbnQgU2VsZWN0ZWQgYXQgbGVhc3QgT25jZSBmcm9tIHRoZSByYWluIG1lbnUnLAojICAgICB4ID0gJ0NvbnRlbnQgU2VsZWN0ZWQnLAojICAgICB5PSAnY291bnQnCiMgICApCgoKCiNET0lORyBJVCBCWSBDQUxMISEhIQpyYWluX21lbnVfY2FsbCA8LSBmaWx0ZXIobG9nX2RhdGEsIGdyZXBsKCJNQUlOIE1FTlUgLSAiLGxvZ0luZm8pKQpyYWluX21lbnVfY2FsbCA8LSBmaWx0ZXIocmFpbl9tZW51X2NhbGwsICFncmVwbCgiTElWRVNUT0NLIE1BSU4gTUVOVSIsbG9nSW5mbykpCnJhaW5fbWVudV9jYWxsIDwtIGZpbHRlcihyYWluX21lbnVfY2FsbCwgIWdyZXBsKCJISEkgTUFJTiBNRU5VIixsb2dJbmZvKSkKcmFpbl9tZW51X2NhbGwgPC0gZmlsdGVyKHJhaW5fbWVudV9jYWxsLCAhZ3JlcGwoIkNPVklELTE5IE1BSU4gTUVOVSIsbG9nSW5mbykpCgojZ3JvdXBpbmcgdGhlIG9ic2VydmF0aW9ucwpyYWluX21lbnVfY2FsbDwtcmFpbl9tZW51X2NhbGwgJT4lCiAgZ3JvdXBfYnkoY2FsbElkLCBsb2dJbmZvLCkgJT4lCiAgY291bnQoKQoKcmFpbl9tZW51X2NhbGw8LSByYWluX21lbnVfY2FsbFttYXRjaCh1bmlxdWUocmFpbl9tZW51X2NhbGwkY2FsbElkKSwgcmFpbl9tZW51X2NhbGwkY2FsbElkKSxdCgpyYWluX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UocmFpbl9tZW51X2NhbGwkbG9nSW5mbywgIk1BSU4gTUVOVSAtICIsICIiKQpyYWluX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UocmFpbl9tZW51X2NhbGwkbG9nSW5mbywgIiBTRUxFQ1RFRCIsICIiKQpyYWluX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UocmFpbl9tZW51X2NhbGwkbG9nSW5mbywgIiBQUkVTU0VEIiwgIiIpCnJhaW5fbWVudV9jYWxsJGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX21lbnVfY2FsbCRsb2dJbmZvLCAiIE9QVElPTiIsICIiKQoKCiNGSXhpbmcgdGhlIEhISSBtZW51IGFuZCBhZGRpbmcgbnVtYmVlcnMKcmFpbl9tZW51X2NhbGwkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHJhaW5fbWVudV9jYWxsJGxvZ0luZm8sICJQUkUgUExBTlRJTkciLCAiUFJFUExBTlRJTkciKQpyYWluX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UocmFpbl9tZW51X2NhbGwkbG9nSW5mbywgIlBMQU5USU5HIiwgIlBMQU5USU5HIikKcmFpbl9tZW51X2NhbGwkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHJhaW5fbWVudV9jYWxsJGxvZ0luZm8sICJDUk9QIFBST1RFQ1RJT04iLCAiQ1JPUCBQUk9URUNUSU9OIikKcmFpbl9tZW51X2NhbGwkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHJhaW5fbWVudV9jYWxsJGxvZ0luZm8sICJGRVJUSUxJWkVSIFNJREUgRFJFU1NJTkciLCAiRkVSVElMSVpFUiBEUkVTU0lORyIpCnJhaW5fbWVudV9jYWxsJGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX21lbnVfY2FsbCRsb2dJbmZvLCAiUE9TVCBIQVJWRVNUIEFORCBQUk9DRVNTSU5HIiwgIlBPU1QgSEFSVkVTVCIpCnJhaW5fbWVudV9jYWxsJGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX21lbnVfY2FsbCRsb2dJbmZvLCAiR08gVE8gTUFJTiBNRU5VIiwgIk5PTi1OVU1FUklDIEtFWSIpCnJhaW5fbWVudV9jYWxsJGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX21lbnVfY2FsbCRsb2dJbmZvLCAiTUFJTiBNRU5VIFJFUExBWUVEIiwgIk5PTi1OVU1FUklDIEtFWSIpCnJhaW5fbWVudV9jYWxsJGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX21lbnVfY2FsbCRsb2dJbmZvLCAiSU5WQUxJRCBLRVkiLCAiTk9OLU5VTUVSSUMgS0VZIikKCiNjN2QwZDggLSBncmV5CiNmY2ZmZjkgLSBjcmVhbQojMTk3MjNmIC0KI3Bsb3R0aW5nIHJhaW4gbWVudSBicmVha2Rvd24KZ2dwbG90KGRhdGE9cmFpbl9tZW51X2NhbGwsIGFlcyh4PWZjdF9pbmZyZXEobG9nSW5mbykpKSArCiAgZ2VvbV9iYXIoY29sb3I9J2JsYWNrJywgZmlsbD0nI2M3ZDBkOCcscG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSggMC4zKSkrCiAgZ2VvbV90ZXh0KHN0YXQ9J2NvdW50JywgYWVzKGxhYmVsPS4uY291bnQuLiksIHZqdXN0PS0xKSsKICBnZW9tX3RleHQoYWVzKHg9J1BSRVBMQU5USU5HJywgeT0xMjAsIGxhYmVsPSdQcmVzcyAxJyksY29sb3I9J2JsYWNrJykrCiAgZ2VvbV90ZXh0KGFlcyh4PSdQTEFOVElORycsIHk9MTIwLCBsYWJlbD0nUHJlc3MgMicpLGNvbG9yPSdibGFjaycpKwogIGdlb21fdGV4dChhZXMoeD0nQ1JPUCBQUk9URUNUSU9OJywgeT0xMjAsIGxhYmVsPSdQcmVzcyAzJyksY29sb3I9J2JsYWNrJykrCiAgZ2VvbV90ZXh0KGFlcyh4PSdGRVJUSUxJWkVSIERSRVNTSU5HJywgeT0xMjAsIGxhYmVsPSdQcmVzcyA0JyksY29sb3I9J2JsYWNrJykrCiAgZ2VvbV90ZXh0KGFlcyh4PSdQT1NUIEhBUlZFU1QnLCB5PTEyMCwgbGFiZWw9J1ByZXNzIDUnKSxjb2xvcj0nYmxhY2snKSsKICBnZW9tX3RleHQoYWVzKHg9J05PTi1OVU1FUklDIEtFWScsIHk9MTIwLCBsYWJlbD0nUHJlc3MgIy8qJyksY29sb3I9J2JsYWNrJykrCiAgeWxpbSgwLDI4MDApKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0xLGNvbG9yPSdibGFjaycpLAogICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNmY2ZmZjkiKSwKICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNmY2ZmZjkiKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKHNpemU9LjEsY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShzaXplPS4xLGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnggPSBlbGVtZW50X2JsYW5rKCkpKwogIGxhYnMoCiAgICB0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgT3B0aW9ucyBTZWxlY3RlZCcsCiAgICB4ID0gJ1JhaW4gTWVudSBPcHRpb25zJywKICAgIHk9J0ZyZXF1ZW5jeScKICApCgojR0VUVElORyBISEkgTUVOVSBQRVIgQ0FMTApISElfbWVudV9jYWxsIDwtIGZpbHRlcihsb2dfZGF0YSwgZ3JlcGwoIkhISSBNQUlOIE1FTlUgLSAiLGxvZ0luZm8pKQoKI2dyb3VwaW5nIHRoZSBvYnNlcnZhdGlvbnMKSEhJX21lbnVfY2FsbDwtSEhJX21lbnVfY2FsbCAlPiUKICBncm91cF9ieShjYWxsSWQsIGxvZ0luZm8sKSAlPiUKICBjb3VudCgpCgpISElfbWVudV9jYWxsPC0gSEhJX21lbnVfY2FsbFttYXRjaCh1bmlxdWUoSEhJX21lbnVfY2FsbCRjYWxsSWQpLCBISElfbWVudV9jYWxsJGNhbGxJZCksXQoKSEhJX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoSEhJX21lbnVfY2FsbCRsb2dJbmZvLCAiSEhJIE1BSU4gTUVOVSAtICIsICIiKQpISElfbWVudV9jYWxsJGxvZ0luZm88LSBzdHJfcmVwbGFjZShISElfbWVudV9jYWxsJGxvZ0luZm8sICIgU0VMRUNURUQiLCAiIikKSEhJX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoSEhJX21lbnVfY2FsbCRsb2dJbmZvLCAiIFBSRVNTRUQiLCAiIikKSEhJX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoSEhJX21lbnVfY2FsbCRsb2dJbmZvLCAiIE9QVElPTiIsICIiKQoKCiNGSXhpbmcgdGhlIEhISSBtZW51IGFuZCBhZGRpbmcgbnVtYmVlcnMKSEhJX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoSEhJX21lbnVfY2FsbCRsb2dJbmZvLCAiUFJFIFBMQU5USU5HIiwgIlBSRVBMQU5USU5HIikKSEhJX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoSEhJX21lbnVfY2FsbCRsb2dJbmZvLCAiUExBTlRJTkcgQU5EIFRSQU5TUExBTlRJTkciLCAiUExBTlRJTkciKQpISElfbWVudV9jYWxsJGxvZ0luZm88LSBzdHJfcmVwbGFjZShISElfbWVudV9jYWxsJGxvZ0luZm8sICJIQVJST1dJTkcgQU5EIEVBUlRITklORyIsICJIQVJST1dJTkciKQpISElfbWVudV9jYWxsJGxvZ0luZm88LSBzdHJfcmVwbGFjZShISElfbWVudV9jYWxsJGxvZ0luZm8sICJJUlJJR0FUSU5HIENST1BTIiwgIklSUklHQVRFIENST1BTIikKSEhJX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoSEhJX21lbnVfY2FsbCRsb2dJbmZvLCAiUFJPVEVDVElORyBDUk9QUyIsICJQUk9URUNUIENST1BTIikKSEhJX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoSEhJX21lbnVfY2FsbCRsb2dJbmZvLCAiQVBQTFlJTkcgRkVSVElMSVpFUiIsICJBUFBMWSBGRVJUSUxJWkVSIikKSEhJX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoSEhJX21lbnVfY2FsbCRsb2dJbmZvLCAiSEFSVkVTVElORyBBTkQgUFJPQ0VTU0lORyIsICJIQVJWRVNUSU5HIikKSEhJX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoSEhJX21lbnVfY2FsbCRsb2dJbmZvLCAiR08gVE8gTUFJTiBNRU5VIiwgIk5PTi1OVU1FUklDIEtFWSIpCkhISV9tZW51X2NhbGwkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKEhISV9tZW51X2NhbGwkbG9nSW5mbywgIkhISSBNQUlOIE1FTlUgUkVQTEFZRUQiLCAiTk9OLU5VTUVSSUMgS0VZIikKSEhJX21lbnVfY2FsbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoSEhJX21lbnVfY2FsbCRsb2dJbmZvLCAiSU5WQUxJRCBLRVkiLCAiTk9OLU5VTUVSSUMgS0VZIikKCiMgdGhlbWUocGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI2ZjZmZmOSIpLAojICAgICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZmNmZmY5IiksCiMgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI2ZjZmZmOSIpLAojICAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplPS4xLGNvbG91ciA9ICJibGFjayIpKQoKI3Bsb3R0aW5nIHJhaW4gbWVudSBicmVha2Rvd24KZ2dwbG90KGRhdGE9SEhJX21lbnVfY2FsbCwgYWVzKHg9ZmN0X2luZnJlcShsb2dJbmZvKSkpICsKICBnZW9tX2Jhcihjb2xvcj0nYmxhY2snLCBmaWxsPScjMTk3MjNmJyxwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCAwLjMpKSsKICBnZW9tX3RleHQoc3RhdD0nY291bnQnLCBhZXMobGFiZWw9Li5jb3VudC4uKSwgdmp1c3Q9LTEpKwogIGdlb21fdGV4dChhZXMoeD0nUFJFUExBTlRJTkcnLCB5PTUwLCBsYWJlbD0nUHJlc3MgMScpLGNvbG9yPScjZmNmZmY5JykrCiAgZ2VvbV90ZXh0KGFlcyh4PSdQTEFOVElORycsIHk9NTAsIGxhYmVsPSdQcmVzcyAyJyksY29sb3I9JyNmY2ZmZjknKSsKICBnZW9tX3RleHQoYWVzKHg9J0hBUlJPV0lORycsIHk9NTAsIGxhYmVsPSdQcmVzcyAzJyksY29sb3I9JyNmY2ZmZjknKSsKICBnZW9tX3RleHQoYWVzKHg9J0lSUklHQVRFIENST1BTJywgeT01MCwgbGFiZWw9J1ByZXNzIDQnKSxjb2xvcj0nI2ZjZmZmOScpKwogIGdlb21fdGV4dChhZXMoeD0nUFJPVEVDVCBDUk9QUycsIHk9NTAsIGxhYmVsPSdQcmVzcyA1JyksY29sb3I9JyNmY2ZmZjknKSsKICBnZW9tX3RleHQoYWVzKHg9J0FQUExZIEZFUlRJTElaRVInLCB5PTUwLCBsYWJlbD0nUHJlc3MgNicpLGNvbG9yPScjZmNmZmY5JykrCiAgZ2VvbV90ZXh0KGFlcyh4PSdIQVJWRVNUSU5HJywgeT01MCwgbGFiZWw9J1ByZXNzIDcnKSxjb2xvcj0nI2ZjZmZmOScpKwogIGdlb21fdGV4dChhZXMoeD0nTk9OLU5VTUVSSUMgS0VZJywgeT01MCwgbGFiZWw9J1ByZXNzICMvKicpLGNvbG9yPScjZmNmZmY5JykrCiAgeWxpbSgwLDEyNTApKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0xKSwKICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZmNmZmY5IiksCiAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZmNmZmY5IiksCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplPS4xLGNvbG91ciA9ICJibGFjayIpLAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUoc2l6ZT0uMSxjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpKSsKICBsYWJzKAogICAgdGl0bGUgPSAnRGlzdHJpYnV0aW9uIG9mIE9wdGlvbnMgU2VsZWN0ZWQnLAogICAgeCA9ICdISEkgTWVudSBPcHRpb25zJywKICAgIHk9J0ZyZXF1ZW5jeScKICApCmBgYAoKCgoqKldlIGNhbiBzZWUgdGhhdCB0aGUgcHJlLXBsYW50aW5nIG1lbnUsIHdoaWNoIHN0aWxsIGhhcyBvdmVyIDc1JSBvZiB1bmlxdWUgdXNlcnMgYWNjZXNzcyBpdCBhdCBsZWFzdCBvbmNlIGV4cGVyZWluY2VzIGluY3JlZGlibHkgaGlnaCB1c2FnZS4gU28sIHdlIG5vdyBkaXZlIGludG8gdGhpcyBtZW51LiBXZSB3aWxsIGJyZWFrZG93biBjb25lbnQgc2VsZWN0aW9uIGJ5IGxhbmd1YWdlIGFuZCBvdmVyYWxsKioKCgojIyMgUkFJTiBNRU5VL1BSRSBQTEFOVElORyBNRU5VCgojIyMjIyBJTkNPTUlORyBDQUxMIFNUQVJURUQgLS0+IFdFTENPTUUgTUVTU0FHRSBQTEFZRUQgLS0+IFJBTkRPTSBFWFBFUklNRU5UIC0tPiAKIyMjIyMgVE9QIE1FTlUgLS0+IFJBSU4gTUVOVSAtLT4gUFJFIFBMQU5USU5HIE1FTlUKCioqUGxlYXNlIG5vdGUsIHRoZSBwcmUgcGxhbnRpbmcgbWVudSB1bmRlciB0aGUgcmFpbiBtZW51IGlzIHJlZmVycmVkIHRvIGFzIE1FTlUgMSBpbiB0aGUgZGF0YSoqCgoKKipQUkUgUExBTlRJTkcgTUVOVSoqCgogLSBMQU5EIFBSRVBBUkFUSU9OCiAtIFNFRUQgVkFSSUVUWQogLSBSRVBFQVQgTUVOVQogLSBHTyBUTyBNQUlOIE1FTlUgKFJBSU4gTUVOVSkKIC0gSU5WQUxJRCBLRVkgKEFERElUSU9OQUwgT1VUQ09NRSkKIAogCmBgYHtyfQoKCiNmaWx0ZXJpbmcgb3V0IE1FTlUgMSBvcHRpb25zIGFzIHRoZSBwcmUgcGxhbnRpbmcKTUVOVV8xIDwtIGZpbHRlcihsb2dfZGF0YSwgZ3JlcGwoIk1FTlUgMSIsbG9nSW5mbykpCk1FTlVfMSA8LSBmaWx0ZXIoTUVOVV8xLCAhZ3JlcGwoIkhISU1FTlUgMSIsbG9nSW5mbykpCk1FTlVfMSA8LSBmaWx0ZXIoTUVOVV8xLCAhZ3JlcGwoIkFQSUNVTFRVUkUgTUVOVSIsbG9nSW5mbykpCk1FTlVfMSA8LSBmaWx0ZXIoTUVOVV8xLCAhZ3JlcGwoIkFQSUNVTFRVUkUgU1VCNCBNRU5VIixsb2dJbmZvKSkKTUVOVV8xIDwtIGZpbHRlcihNRU5VXzEsICFncmVwbCgiREFJUlkgTUVOVSIsbG9nSW5mbykpCk1FTlVfMSA8LSBmaWx0ZXIoTUVOVV8xLCAhZ3JlcGwoIlNNQUxMLVNDQUxFIFNVQjUgTUVOVSIsbG9nSW5mbykpCk1FTlVfMSA8LSBmaWx0ZXIoTUVOVV8xLCAhZ3JlcGwoIkRBSVJZIFNVQjIgTUVOVSIsbG9nSW5mbykpCk1FTlVfMSA8LSBmaWx0ZXIoTUVOVV8xLCAhZ3JlcGwoIkZBVFRFTklORyBNQU5VIixsb2dJbmZvKSkKCk1FTlVfMSA8LSBmaWx0ZXIoTUVOVV8xLCAhZ3JlcGwoIkZBVFRFTklORyBTVUIxIE1FTlUiLGxvZ0luZm8pKQpNRU5VXzEgPC0gZmlsdGVyKE1FTlVfMSwgIWdyZXBsKCJGQVRURU5JTkcgU1VCMiBNRU5VIixsb2dJbmZvKSkKTUVOVV8xIDwtIGZpbHRlcihNRU5VXzEsICFncmVwbCgiSE9VU0VIT0xEIE1FTlUiLGxvZ0luZm8pKQpNRU5VXzEgPC0gZmlsdGVyKE1FTlVfMSwgIWdyZXBsKCJIT1VTRUhPTEQgU1VCMSBNRU5VICIsbG9nSW5mbykpCgoKTUVOVV8xIDwtIE1FTlVfMSAlPiUKICBncm91cF9ieShjYWxsZXJJZCwgbG9nSW5mbywgbGFuZ0lkKSAlPiUKICBjb3VudCgpCgpNRU5VXzEkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKE1FTlVfMSRsb2dJbmZvLCAiTUVOVSAxIC0gIiwgIiIpCk1FTlVfMSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoTUVOVV8xJGxvZ0luZm8sICIgUFJFU1NFRCIsICIiKQpNRU5VXzEkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKE1FTlVfMSRsb2dJbmZvLCAiIFNFTEVDVEVEIiwgIiIpCgojIHBsb3R0aW5nCmdncGxvdChkYXRhPU1FTlVfMSwgYWVzKHg9bG9nSW5mbykpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDI1LCBoanVzdD0gMSkpKwogIGdlb21fYmFyKGZpbGw9J2N5YW4nKSsKICBsYWJzKAogICAgdGl0bGUgPSAnSW5kaXZpZHVhbHMgQnkgQ29udGVudCBTZWxlY3RlZCBhdCBsZWFzdCBPbmNlIGZyb20gCiAgICBSQUlOIE1FTlUvUFJFIFBMQU5USU5HIE9QVElPTicsCiAgICB4ID0gJ0NvbnRlbnQgU2VsZWN0ZWQnLAogICAgeT0gJ2NvdW50JwogICkKCgoKYGBgCgoKIyMjIFJBSU4gTUVOVS9QUkUgUExBTlRJTkcgTUVOVS9MQU5EIFBSRVBBUkFUSU9OCgoKKipXZSBjb250aW51ZSBvdXIgcGF0dGVybiBvZiBmb2xsb3dpbmcgdGhlIG1vc3QgYWNjZXNzZWQgc3VibWVudSBmcm9tIHRoZSBwcmV2aW91cyBzdWJtZW50IC0gbGFuZCBwcmVwYXJhdGlvbiEgVGhpcyBpcyBhbHNvIHRoZSBib3R0b20gb2YgYSB0cmVlLiBXZSB3aWxsIGJyZWFrZG93biBjb25lbnQgc2VsZWN0aW9uIGJ5IGxhbmd1YWdlIGFuZCBvdmVyYWxsKioKCgojIyMjIyBJTkNPTUlORyBDQUxMIFNUQVJURUQgLS0+IFdFTENPTUUgTUVTU0FHRSBQTEFZRUQgLS0+IFJBTkRPTSBFWFBFUklNRU5UIC0tPiAKIyMjIyMgVE9QIE1FTlUgLS0+IFJBSU4gTUVOVSAtLT4gUFJFIFBMQU5USU5HIE1FTlUgLS0+IExBTkQgUFJFUEFSQVRJT04KCioqTEFORCBQUkVQQVJBVElPTioqCgogLSBCQVJMRVkKIC0gTUFJWkUKIC0gU09SR0hVTQogLSBURUYKIC0gV0hFQVQKIC0gU0VTQU1FCiAtIEZBVkEgQkVBTgogLSBDSElDS1BFQQogLSBDT01NT04gQkVBTgogLSBDT1RUT04KCk9SREVSIFVOS09XTjoKCiAtIFJJQ0UKIC0gRFVSQU1FIFdIRUFUCiAtIExFTlRJTAogLSBNQUxUIEJBUkxFWQogCiAKYGBge3J9CiNHRVRUSU5HIFRIRSBDUk9QIE1FTlUgRlJPTSBNRU5VIDEgKHJhaW4vcHJlcGxhbnRpbmcvbGFuZCBwcmVwYXJhdGlvbiBzdWIgbWVudSkKbGFuZF9wcmVwIDwtIGZpbHRlcihsb2dfZGF0YSwgZ3JlcGwoIkNPTlRFTlQgUExBWUVEIC0gTEFORCBQUkVQQVJBVElPTiAtICIsbG9nSW5mbykpCgpsYW5kX3ByZXBfZmluYWwgPC0gbGFuZF9wcmVwICU+JQogIGdyb3VwX2J5KGNhbGxlcklkLCBsb2dJbmZvLCBsYW5nSWQpICU+JQogIGNvdW50KCkKCmxhbmRfcHJlcF9maW5hbCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UobGFuZF9wcmVwX2ZpbmFsJGxvZ0luZm8sICJDT05URU5UIFBMQVlFRCAtIExBTkQgUFJFUEFSQVRJT04gLSIsICIiKQoKZ2dwbG90KGRhdGE9bGFuZF9wcmVwX2ZpbmFsLCBhZXMoeD1sb2dJbmZvKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0PTIpKSsKICBnZW9tX2JhcigpKwogIGxhYnMoCiAgICB0aXRsZSA9ICdSQUlOIE1FTlUvUFJFIFBMQU5USU5HL0xBTkQgUFJFUEFSQVRJT04KICAgIGNvbnRlbnQgYWN0dWFsbHkgcGxheWVkIGJ5IGxhbmd1YWdlJywKICAgIHggPSAnQ29udGVudCBQbGF5ZWQnLAogICAgeT0gJ2NvdW50JwogICkKCgojZ2V0IHJpZCBvZiB0aGUgbGFuZ3VhZ2UgYnJlYWtkb3duCmxhbmRfcHJlcF9ub19sYW5nIDwtIGxhbmRfcHJlcF9maW5hbAoKbGFuZF9wcmVwX25vX2xhbmckbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGxhbmRfcHJlcF9ub19sYW5nJGxvZ0luZm8sICItIEFNSEFSSUMiLCAiIikKbGFuZF9wcmVwX25vX2xhbmckbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGxhbmRfcHJlcF9ub19sYW5nJGxvZ0luZm8sICItIE9ST01JRkZBIiwgIiIpCmxhbmRfcHJlcF9ub19sYW5nJGxvZ0luZm88LSBzdHJfcmVwbGFjZShsYW5kX3ByZXBfbm9fbGFuZyRsb2dJbmZvLCAiLSBUSUdSSUdOQSIsICIiKQpsYW5kX3ByZXBfbm9fbGFuZyRsb2dJbmZvPC0gc3RyX3JlcGxhY2UobGFuZF9wcmVwX25vX2xhbmckbG9nSW5mbywgIi0gV09MQVlJVFRBIiwgIiIpCmxhbmRfcHJlcF9ub19sYW5nJGxvZ0luZm88LSBzdHJfcmVwbGFjZShsYW5kX3ByZXBfbm9fbGFuZyRsb2dJbmZvLCAiLSBXT0xBWVRJR05BIiwgIiIpCmxhbmRfcHJlcF9ub19sYW5nJGxvZ0luZm88LSBzdHJfcmVwbGFjZShsYW5kX3ByZXBfbm9fbGFuZyRsb2dJbmZvLCAiLSBTSURBTUlHTkEiLCAiIikKCmdncGxvdChsYW5kX3ByZXBfbm9fbGFuZywgYWVzKHg9bG9nSW5mbykpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkrCiAgZ2VvbV9iYXIoKSsKICBsYWJzKAogICAgdGl0bGUgPSAnUkFJTiBNRU5VL1BSRSBQTEFOVElORy9MQU5EIFBSRVBBUkFUSU9OCiAgICBjb250ZW50IHBsYXllZCBvdmVyYWxsJywKICAgIHggPSAnQ29udGVudCBQbGF5ZWQnLAogICAgeT0gJ2NvdW50JwogICkKCmdncGxvdChsYW5kX3ByZXBfbm9fbGFuZywgYWVzKGxhbmdJZCwgZmlsbCA9IGxvZ0luZm8pKSArCiAgZ2VvbV9iYXIoKSsKICBsYWJzKAogICAgdGl0bGUgPSAnQUxURVJOQVRJVkUgUkFJTiBNRU5VL1BSRSBQTEFOVElORy9MQU5EIFBSRVBBUkFUSU9OCiAgICBjb250ZW50IGFjdHVhbGx5IHBsYXllZCBieSBsYW5ndWFnZQogICAgMSA9IEFtaGFyaWMsIDI9T3JvbWlmZmEsIDM9VGlncmlnbmEsIDQ9V29sYXlpdHRhLCBhbmQgNT1TaWRhbWlnbmEKICAgICcsCiAgICB4ID0gJ0xhbmd1YWdlJwogICkKYGBgCiAKCioqQklHIFRBS0VBV0FZOiAzNSUgb2YgdXNlcnMgZW5kIHVwIGFjY2Vzc2luZyB0aGUgbWFpemUgbWVudSBhdCBzb21lIHBvaW50ISBXaGVhdCwgVGVmLCBTb3JnaHVtLCBhbmQgQmFybGV5IGFsc28gYXBwZWFyIHRvIGJlIHF1YWxpdGF0aXZlbHkgc2lnbmlmaWNhbnQqKgoKKipUaGVyZSBpcyBubyBtZW51IHRvIGdvIGRlZXBlciBpbiwgc28gbGV0J3MgZ28gYmFjayB1cCBhIGxldmVsIGFuZCBjaGVjayB0byBzZWUgaWYgb3RoZXIgYnJhbmNoZXMgaGF2ZSBhIGxvdCBvZiBhY2Nlc3MqKgoKCiMjIyBSQUlOIE1FTlUvUFJFIFBMQU5USU5HIE1FTlUvU0VFRCBWQVJJRVRZCgoKIyMjIyMgSU5DT01JTkcgQ0FMTCBTVEFSVEVEIC0tPiBXRUxDT01FIE1FU1NBR0UgUExBWUVEIC0tPiBSQU5ET00gRVhQRVJJTUVOVCAtLT4gCiMjIyMjIFRPUCBNRU5VIC0tPiBSQUlOIE1FTlUgLS0+IFBSRSBQTEFOVElORyBNRU5VIC0tPiBTRUVEIFZBUklFVFkKCioqU0VFRCBWQVJJRVRZKioKCiAtIEJBUkxFWQogLSBNQUlaRQogLSBTT1JHSFVNCiAtIFRFRgogLSBXSEVBVAogLSBTRVNBTUUKIC0gRkFWQSBCRUFOCiAtIENISUNLUEVBCiAtIENPTU1PTiBCRUFOCgpgYGB7cn0KI0dFVFRJTkcgVEhFIENST1AgTUVOVSBGUk9NIE1FTlUgMSAocmFpbi9wcmVwbGFudGluZy9zZWVkIHZhcmlldHkgc3ViIG1lbnUpCnNlZWRfdmFyaWV0eSA8LSBmaWx0ZXIobG9nX2RhdGEsIGdyZXBsKCJDT05URU5UIFBMQVlFRCAtIFNFRUQgVkFSSVRZIixsb2dJbmZvKSkKCnNlZWRfdmFyaWV0eV9maW5hbCA8LSBzZWVkX3ZhcmlldHkgJT4lCiAgZ3JvdXBfYnkoY2FsbGVySWQsIGxvZ0luZm8sIGxhbmdJZCkgJT4lCiAgY291bnQoKQoKc2VlZF92YXJpZXR5X2ZpbmFsJGxvZ0luZm88LSBzdHJfcmVwbGFjZShzZWVkX3ZhcmlldHlfZmluYWwkbG9nSW5mbywgIkNPTlRFTlQgUExBWUVEIC0gU0VFRCBWQVJJVFkgLSAiLCAiIikKCmdncGxvdChkYXRhPXNlZWRfdmFyaWV0eV9maW5hbCwgYWVzKHg9bG9nSW5mbykpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdD0xKSkrCiAgZ2VvbV9iYXIoKSsKICBsYWJzKAogICAgdGl0bGUgPSAnUkFJTiBNRU5VL1BSRSBQTEFOVElORy9TRUVEIFZBUklFVFkKICAgIGNvbnRlbnQgYWN0dWFsbHkgcGxheWVkIGJ5IGxhbmd1YWdlJywKICAgIHggPSAnQ29udGVudCBTZWxlY3RlZCcsCiAgICB5PSAnY291bnQnCiAgKQoKCiNnZXQgcmlkIG9mIHRoZSBsYW5ndWFnZSBicmVha2Rvd24Kc2VlZF92YXJpZXR5X25vX2xhbmcgPC0gc2VlZF92YXJpZXR5X2ZpbmFsCgpzZWVkX3ZhcmlldHlfbm9fbGFuZyRsb2dJbmZvPC0gc3RyX3JlcGxhY2Uoc2VlZF92YXJpZXR5X25vX2xhbmckbG9nSW5mbywgIi0gQU1IQVJJQyIsICIiKQpzZWVkX3ZhcmlldHlfbm9fbGFuZyRsb2dJbmZvPC0gc3RyX3JlcGxhY2Uoc2VlZF92YXJpZXR5X25vX2xhbmckbG9nSW5mbywgIi0gT1JPTUlGRkEiLCAiIikKc2VlZF92YXJpZXR5X25vX2xhbmckbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHNlZWRfdmFyaWV0eV9ub19sYW5nJGxvZ0luZm8sICItIFRJR1JJR05BIiwgIiIpCnNlZWRfdmFyaWV0eV9ub19sYW5nJGxvZ0luZm88LSBzdHJfcmVwbGFjZShzZWVkX3ZhcmlldHlfbm9fbGFuZyRsb2dJbmZvLCAiLSBXT0xBWUlUVEEiLCAiIikKc2VlZF92YXJpZXR5X25vX2xhbmckbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHNlZWRfdmFyaWV0eV9ub19sYW5nJGxvZ0luZm8sICItIFdPTEFZVElHTkEiLCAiIikKc2VlZF92YXJpZXR5X25vX2xhbmckbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHNlZWRfdmFyaWV0eV9ub19sYW5nJGxvZ0luZm8sICItIFNJREFNSUdOQSIsICIiKQoKI2FsdGVybmF0aXZlIHdpdGggbGFuZ2F1Z2UgdmlldwpnZ3Bsb3Qoc2VlZF92YXJpZXR5X25vX2xhbmcsIGFlcyhsYW5nSWQsIGZpbGwgPSBsb2dJbmZvKSkgKwogIGdlb21fYmFyKCkrCiAgbGFicygKICAgIHRpdGxlID0gJ0FMVEVSTkFUSVZFIFJBSU4gTUVOVS9QUkUgUExBTlRJTkcvU0VFIFZBUklFVFkKICAgIGNvbnRlbnQgYWN0dWFsbHkgcGxheWVkIGJ5IGxhbmd1YWdlCiAgICAxID0gQW1oYXJpYywgMj1Pcm9taWZmYSwgMz1UaWdyaWduYSwgND1Xb2xheWl0dGEsIGFuZCA1PVNpZGFtaWduYQogICAgJywKICAgIHggPSAnTGFuZ3VhZ2UnCiAgKQoKI25vIGxhbmd1YWdlIC0gb3ZlcmFsbApnZ3Bsb3Qoc2VlZF92YXJpZXR5X25vX2xhbmcsIGFlcyh4PWxvZ0luZm8pKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwgaGp1c3Q9MSkpKwogIGdlb21fYmFyKCkrCiAgbGFicygKICAgIHRpdGxlID0gJ1JBSU4gTUVOVS9QUkUgUExBTlRJTkcvc2VlZCB2YXJpZXR5CiAgICBjb250ZW50IGFjdHVhbGx5IHBsYXllZCcsCiAgICB4ID0gJ0NvbnRlbnQgU2VsZWN0ZWQnLAogICAgeT0gJ2NvdW50JwogICkKCgpgYGAKIAoqKldlIGhhdmUgbW9zdGx5IGV4aGF1c3RlZCB0aGUgcHJlLXBsYW50aW5nIG9wdGlvbiBtZW51LCBhbmQgaWYgd2UgZ28gYmFjayB1cCB0byB0aGUgb3JpZ2luYWwgcmFpbiBtZW51IChha2EgTUFJTiBNRU5VKSwgd2UgY2FuIHNlZSB0aGF0IHBsYW50aW5nIGFsc28gaGFzIGEgbGFyZ2UgcG9ycG9ydGlvbiBvZiB1c2VycyAtIG92ZXIgaGFsZioqCgoKIyMjIFJBSU4gTUVOVS9QTEFOVElORyBNRU5VCgoKIyMjIyMgSU5DT01JTkcgQ0FMTCBTVEFSVEVEIC0tPiBXRUxDT01FIE1FU1NBR0UgUExBWUVEIC0tPiBSQU5ET00gRVhQRVJJTUVOVCAtLT4gCiMjIyMjIFRPUCBNRU5VIC0tPiBSQUlOIE1FTlUgLS0+IFBMQU5USU5HIE1FTlUKCioqVGhlIHBsYW50aW5nIG9wdGlvbiBhcyBhIHN1YnNlY3Rpb24gb2YgdGhlIHJhaW4gb3B0aW9uIGlzIGtub3duIGFzIE1FTlUgMiBpbiB0aGUgZGF0YSoqCgpQTEFOVElORyBNRU5VCgogLSBTRUVEIFJBVEUKIC0gU09JTCBERVBUSCBQTEFOVElORwogLSBUUkFOU1BMQU5USU5HCiAtIE1PSVNUVVJFIENPTlNFUlZBVElPTgogLSBGRVJUSUxJWkVSIEFQUExJQ0FUSU9OCiAtIFJFUExBWSBNRU5ZCiAtIFJFVFVSTiBUTyBSQUlOIE1FTlkKIC0gSU5WQUxJRCBLRVkgKEFERElUSU9OQUwgT1VUQ09NRSkKIAoKCmBgYHtyfQojUExBTlRJTkcgT1BUSU9OIC0gc2Vjb25kIG1vc3QgYWNjZXNzZWQgTUVOVSAyCk1FTlVfMiA8LSBmaWx0ZXIobG9nX2RhdGEsIGdyZXBsKCJNRU5VIDIiLGxvZ0luZm8pKQpNRU5VXzIgPC0gZmlsdGVyKE1FTlVfMiwgIWdyZXBsKCJISElNRU5VIDIiLGxvZ0luZm8pKQpNRU5VXzIgPC0gZmlsdGVyKE1FTlVfMiwgIWdyZXBsKCJBUElDVUxUVVJFIE1FTlUiLGxvZ0luZm8pKQpNRU5VXzIgPC0gZmlsdGVyKE1FTlVfMiwgIWdyZXBsKCJBUElDVUxUVVJFIFNVQjIgTUVOVSIsbG9nSW5mbykpCk1FTlVfMiA8LSBmaWx0ZXIoTUVOVV8yLCAhZ3JlcGwoIkRBSVJZIE1FTlUiLGxvZ0luZm8pKQpNRU5VXzIgPC0gZmlsdGVyKE1FTlVfMiwgIWdyZXBsKCJGQVRURU5JTkcgTUFOVSIsbG9nSW5mbykpCgpNRU5VXzIgPC0gTUVOVV8yICU+JQogIGdyb3VwX2J5KGNhbGxlcklkLCBsb2dJbmZvLCBsYW5nSWQpICU+JQogIGNvdW50KCkKCiNjbGVhbmluZwpNRU5VXzIkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKE1FTlVfMiRsb2dJbmZvLCAiTUVOVSAyIC0gIiwgIiIpCk1FTlVfMiRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoTUVOVV8yJGxvZ0luZm8sICIgU0VMRUNURUQiLCAiIikKTUVOVV8yJGxvZ0luZm88LSBzdHJfcmVwbGFjZShNRU5VXzIkbG9nSW5mbywgIiBQUkVTU0VEIiwgIiIpCk1FTlVfMiRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoTUVOVV8yJGxvZ0luZm8sICIgT1BUSU9OIiwgIiIpCgoKI3Bsb3R0aW5nCmdncGxvdChkYXRhPU1FTlVfMiwgYWVzKHg9ZmN0X2luZnJlcShsb2dJbmZvKSkpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdD0xKSkrCiAgZ2VvbV9iYXIoZmlsbD0nb2xpdmVkcmFiJykrCiAgbGFicygKICAgIHRpdGxlID0gJ0luZGl2aWR1YWxzIEJ5IENvbnRlbnQgU2VsZWN0ZWQgYXQgbGVhc3QgT25jZSBmcm9tIAogICAgUkFJTiBNRU5VL1BMQU5USU5HIE9QVElPTicsCiAgICB4ID0gJ0NvbnRlbnQgU2VsZWN0ZWQnLAogICAgeT0gJ2NvdW50JwogICkKYGBgCgoKCioqQXMgcGVyIHVzdWFsLCB3ZSB3aWxsIGdvIGludG8gdGhlIG1vc3QgY29tbW9uIHNlbGVjdGlvbjogc2VlZCByYXRlISoqCgojIyMgUkFJTiBNRU5VL1BMQU5USU5HIE1FTlUvU0VFRCBSQVRFCgoKIyMjIyMgSU5DT01JTkcgQ0FMTCBTVEFSVEVEIC0tPiBXRUxDT01FIE1FU1NBR0UgUExBWUVEIC0tPiBSQU5ET00gRVhQRVJJTUVOVCAtLT4gCiMjIyMjIFRPUCBNRU5VIC0tPiBSQUlOIE1FTlUgLS0+IFBMQU5USU5HIE1FTlUgLS0+IFNFRUQgUkFURQoKCioqU0VFRCBSQVRFKioKCiAtIEJBUkxFWQogLSBNQUlaRQogLSBTT1JHSFVNCiAtIFRFRgogLSBXSEVBVAogLSBTRVNBTUUKIC0gRkFWQSBCRUFOCiAtIENISUNLUEVBCiAtIENPTU1PTiBCRUFOCiAtIENPVFRPTgoKT1JERVIgVU5LT1dOOgoKIC0gUklDRQogLSBEVVJBTUUgV0hFQVQKIC0gTEVOVElMCiAtIE1BTFQgQkFSTEVZCgpgYGB7cn0Kc2VlZF9yYXRlIDwtIGZpbHRlcihsb2dfZGF0YSwgZ3JlcGwoIkNPTlRFTlQgUExBWUVEIC0gU0VFRCBSQVRFIixsb2dJbmZvKSkKCnNlZWRfcmF0ZV9maW5hbCA8LSBzZWVkX3JhdGUgJT4lCiAgZ3JvdXBfYnkoY2FsbGVySWQsIGxvZ0luZm8sIGxhbmdJZCkgJT4lCiAgY291bnQoKQoKc2VlZF9yYXRlX2ZpbmFsJGxvZ0luZm88LSBzdHJfcmVwbGFjZShzZWVkX3JhdGVfZmluYWwkbG9nSW5mbywgIkNPTlRFTlQgUExBWUVEIC0gU0VFRCBSQVRFIC0iLCAiIikKCmdncGxvdChkYXRhPXNlZWRfcmF0ZV9maW5hbCwgYWVzKHg9bG9nSW5mbykpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LGhqdXN0PTEpKSsKICBnZW9tX2JhcigpKwogIGxhYnMoCiAgICB0aXRsZSA9ICdSQUlOIE1FTlUvUExBTlRJTkcvU0VFRCBSQVRFCiAgICBjb250ZW50IGFjdHVhbGx5IHBsYXllZCBieSBsYW5ndWFnZScsCiAgICB4ID0gJ0NvbnRlbnQgU2VsZWN0ZWQnLAogICAgeT0gJ2NvdW50JwogICkKCiNnZXQgcmlkIG9mIHRoZSBsYW5ndWFnZSBicmVha2Rvd24Kc2VlZF9yYXRlX25vX2xhbmcgPC0gc2VlZF9yYXRlX2ZpbmFsCgpzZWVkX3JhdGVfbm9fbGFuZyRsb2dJbmZvPC0gc3RyX3JlcGxhY2Uoc2VlZF9yYXRlX25vX2xhbmckbG9nSW5mbywgIi0gQU1IQVJJQyIsICIiKQpzZWVkX3JhdGVfbm9fbGFuZyRsb2dJbmZvPC0gc3RyX3JlcGxhY2Uoc2VlZF9yYXRlX25vX2xhbmckbG9nSW5mbywgIi0gT1JPTUlGRkEiLCAiIikKc2VlZF9yYXRlX25vX2xhbmckbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHNlZWRfcmF0ZV9ub19sYW5nJGxvZ0luZm8sICItIFRJR1JJR05BIiwgIiIpCnNlZWRfcmF0ZV9ub19sYW5nJGxvZ0luZm88LSBzdHJfcmVwbGFjZShzZWVkX3JhdGVfbm9fbGFuZyRsb2dJbmZvLCAiLSBXT0xBWUlUVEEiLCAiIikKc2VlZF9yYXRlX25vX2xhbmckbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHNlZWRfcmF0ZV9ub19sYW5nJGxvZ0luZm8sICItIFdPTEFZVElHTkEiLCAiIikKc2VlZF9yYXRlX25vX2xhbmckbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHNlZWRfcmF0ZV9ub19sYW5nJGxvZ0luZm8sICItIFNJREFNSUdOQSIsICIiKQoKI2FsdGVybmF0aXZlIHdpdGggbGFuZ2F1Z2UgdmlldwpnZ3Bsb3Qoc2VlZF9yYXRlX25vX2xhbmcsIGFlcyhsYW5nSWQsIGZpbGwgPSBsb2dJbmZvKSkgKwogIGdlb21fYmFyKCkrCiAgbGFicygKICAgIHRpdGxlID0gJ0FMVEVSTkFUSVZFIFJBSU4gTUVOVS9QTEFOVElORy9TRUVEIFJBVEUKICAgIGNvbnRlbnQgYWN0dWFsbHkgcGxheWVkIGJ5IGxhbmd1YWdlCiAgICAxID0gQW1oYXJpYywgMj1Pcm9taWZmYSwgMz1UaWdyaWduYSwgND1Xb2xheWl0dGEsIGFuZCA1PVNpZGFtaWduYQogICAgJywKICAgIHggPSAnTGFuZ3VhZ2UnCiAgKQojbm8gbGFuZ3VhZ2UKZ2dwbG90KHNlZWRfcmF0ZV9ub19sYW5nLCBhZXMoeD1sb2dJbmZvKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0PTEpKSsKICBnZW9tX2JhcigpKwogIGxhYnMoCiAgICB0aXRsZSA9ICdSQUlOIE1FTlUvUExBTlRJTkcvU0VFRCBSQVRFCiAgICBjb250ZW50IGFjdHVhbGx5IHBsYXllZCcsCiAgICB4ID0gJ0NvbnRlbnQgU2VsZWN0ZWQnLAogICAgeT0gJ2NvdW50JwogICkKCmBgYAoKCgoKYGBge3J9CmNyb3BfbWVudSA8LSBsb2dfZGF0YSAlPiUKICBmaWx0ZXIoZ3JlcGwoIkNST1AgTUVOVSAtICIsbG9nSW5mbykpICU+JQogIGZpbHRlcighZ3JlcGwoIkhISSIsbG9nSW5mbykpICU+JQogIGZpbHRlcighZ3JlcGwoIlJFUExBWUVEIixsb2dJbmZvKSkKCmNyb3BfbWVudSA8LSBjcm9wX21lbnUgJT4lCiAgZ3JvdXBfYnkoY2FsbGVySWQsIGxvZ0luZm8sIGxhbmdJZCkgJT4lCiAgY291bnQoKQoKY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShjcm9wX21lbnUkbG9nSW5mbywgIkNST1AgTUVOVSAtICIsICIiKQpjcm9wX21lbnUkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNyb3BfbWVudSRsb2dJbmZvLCAiIFNFTEVDVEVEIiwgIiIpCmNyb3BfbWVudSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY3JvcF9tZW51JGxvZ0luZm8sICJHTyBUTyIsICIiKQoKCmdncGxvdChjcm9wX21lbnUsIGFlcyh4PWxvZ0luZm8pKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA2MCwgaGp1c3QgPTEsIHNpemUgPSA3KSkrCiAgZ2VvbV9iYXIoKSsKICBsYWJzKAogICAgdGl0bGUgPSAnQ3JvcCBtZW51IGJyZWFrZG93bicsCiAgICB4ID0gJ0Nyb3BzJywKICAgIHk9ICdjb3VudCcKICApCgpnZ3Bsb3QoY3JvcF9tZW51LCBhZXMobGFuZ0lkLCBmaWxsID0gbG9nSW5mbykpICsKICBnZW9tX2JhcigpKwogIGxhYnMoCiAgICB0aXRsZSA9ICdDUk9QIE1FTlUgQlkgTEFOR1VBR0UKICAgIDEgPSBBbWhhcmljLCAyPU9yb21pZmZhLCAzPVRpZ3JpZ25hLCA0PVdvbGF5aXR0YSwgYW5kIDU9U2lkYW1pZ25hCiAgICAnLAogICAgeCA9ICdMYW5ndWFnZScKICApCm51bV9jcm9wX3R5cGVzIDwtIGRhdGEuZnJhbWUoYXMubnVtZXJpYyh0YWJsZShjcm9wX21lbnUkY2FsbGVySWQpKSkKbnVtX2Nyb3BfdHlwZXMkZnJlcXVlbmNpZXMgPC0gbnVtX2Nyb3BfdHlwZXMkYXMubnVtZXJpYy50YWJsZS5jcm9wX21lbnUuY2FsbGVySWQuCgpzdW1tYXJ5KG51bV9jcm9wX3R5cGVzJGZyZXF1ZW5jaWVzKQoKZ2dwbG90KG51bV9jcm9wX3R5cGVzLCBhZXMoZnJlcXVlbmNpZXMpKSArCiAgZ2VvbV9oaXN0b2dyYW0oY29sb3I9ImJsYWNrIiwgZmlsbD0icmVkIikgKwogIGxhYnMoCiAgICB0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgbnVtYmVyIGNyb3BzIGV2ZXIgc2VsZWN0ZWQgYnkgaW5kaXZpZHVhbCBcbgogICAgICBNaW4uICAxc3QgUXUuICBNZWRpYW4gICAgTWVhbiAgIDNyZCBRdS4gICAgTWF4LiAKICAxLjAwMCAgICAgMi4wMDAgICAgIDQuMDAwICAgICAgNC45MTUgICAgIDcuMDAwICAgICAxNS4wMDAgJywKICAgIHggPSAnTnVtYmVyIG9mIGNyb3BzIHNlbGVjdGVkICcKICApCmBgYAoKCmBgYHtyfQojR0VUVElORyBCT1RIIFRIRSBDUk9QIE1FTlVTIGZvciBib3RoIHJhaW4gYW5kIGhoaQpyYWluX2Nyb3BfbWVudSA8LSBmaWx0ZXIobG9nX2RhdGEsIGdyZXBsKCJDUk9QIE1FTlUgLSAiLGxvZ0luZm8pKQpyYWluX2Nyb3BfbWVudSA8LSBmaWx0ZXIocmFpbl9jcm9wX21lbnUsICFncmVwbCgiSEhJIixsb2dJbmZvKSkKCnJhaW5fY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX2Nyb3BfbWVudSRsb2dJbmZvLCAiQ1JPUCBNRU5VIC0gIiwgIiIpCnJhaW5fY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX2Nyb3BfbWVudSRsb2dJbmZvLCAiIFNFTEVDVEVEIiwgIiIpCnJhaW5fY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX2Nyb3BfbWVudSRsb2dJbmZvLCAiIFBUSU9OIiwgIk9QVElPTiIpCgoKI0FERElORyBUSEUgTlVNQkVSUwpyYWluX2Nyb3BfbWVudSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UocmFpbl9jcm9wX21lbnUkbG9nSW5mbywgIkJBUkxFWSBPUFRJT04iLCAiQkFSTEVZIikKcmFpbl9jcm9wX21lbnUkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHJhaW5fY3JvcF9tZW51JGxvZ0luZm8sICJNQUlaRSBPUFRJT04iLCAiTUFJWkUiKQpyYWluX2Nyb3BfbWVudSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UocmFpbl9jcm9wX21lbnUkbG9nSW5mbywgIlNPUkdIVU0gT1BUSU9OIiwgIlNPUkdIVU0iKQpyYWluX2Nyb3BfbWVudSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UocmFpbl9jcm9wX21lbnUkbG9nSW5mbywgIlRFRiBPUFRJT04iLCAiVEVGIikKcmFpbl9jcm9wX21lbnUkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHJhaW5fY3JvcF9tZW51JGxvZ0luZm8sICJEVVJFTSBXSEVBVCBPUFRJT04iLCAiVU5OVU1CRVJFRCIpCnJhaW5fY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX2Nyb3BfbWVudSRsb2dJbmZvLCAiTUFMVCBCQVJMRVkiLCAiVU5OVU1CRVJFRCIpCnJhaW5fY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX2Nyb3BfbWVudSRsb2dJbmZvLCAiTEVOVElMIiwgIlVOTlVNQkVSRUQiKQpyYWluX2Nyb3BfbWVudSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UocmFpbl9jcm9wX21lbnUkbG9nSW5mbywgIlJJQ0UiLCAiVU5OVU1CRVJFRCIpCnJhaW5fY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX2Nyb3BfbWVudSRsb2dJbmZvLCAiVU5OVU1CRVJFRCBPUFRJT04iLCAiVU5OVU1CRVJFRCIpCnJhaW5fY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX2Nyb3BfbWVudSRsb2dJbmZvLCAiV0hFQVQgT1BUSU9OIiwgIldIRUFUIikKcmFpbl9jcm9wX21lbnUkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHJhaW5fY3JvcF9tZW51JGxvZ0luZm8sICJTRVNBTUUgT1BUSU9OIiwgIlNFU0FNRSIpCnJhaW5fY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX2Nyb3BfbWVudSRsb2dJbmZvLCAiRkFWQSBCRUFOIE9QVElPTiIsICJGQVZBIEJFQU4iKQpyYWluX2Nyb3BfbWVudSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UocmFpbl9jcm9wX21lbnUkbG9nSW5mbywgIkNISUNLUEVBIE9QVElPTiIsICJDSElDS1BFQSIpCnJhaW5fY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShyYWluX2Nyb3BfbWVudSRsb2dJbmZvLCAiQ09NTU9OIEJFQU5PUFRJT04iLCAiQ09NTU9OIEJFQU4iKQpyYWluX2Nyb3BfbWVudSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UocmFpbl9jcm9wX21lbnUkbG9nSW5mbywgIkNPVFRPTiBPUFRJT04iLCAiQ09UVE9OIikKcmFpbl9jcm9wX21lbnUkbG9nSW5mbzwtIG5hX2lmKHJhaW5fY3JvcF9tZW51JGxvZ0luZm8sICJDT1RUT04iKQoKcmFpbl9jcm9wX21lbnUkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHJhaW5fY3JvcF9tZW51JGxvZ0luZm8sICJDUk9QIE1FTlUgUkVQTEFZRUQiLCAiTk9OLU5VTUVSSUMgS0VZIikKcmFpbl9jcm9wX21lbnUkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHJhaW5fY3JvcF9tZW51JGxvZ0luZm8sICJHTyBUTyBNQUlOIE1FTlUgT1BUSU9OIiwgIk5PTi1OVU1FUklDIEtFWSIpCgojZml4ZXMKcmFpbl9jcm9wX21lbnUkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKHJhaW5fY3JvcF9tZW51JGxvZ0luZm8sICJNQUxUIDEgLSAiLCAiTUFMVCAiKQpyYWluX2Nyb3BfbWVudSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UocmFpbl9jcm9wX21lbnUkbG9nSW5mbywgIkRVUkVNIDUgLSAiLCAiRFVSRU0gIikKCgoKI3Bsb3R0aW5nIHJhaW4KZ2dwbG90KHJhaW5fY3JvcF9tZW51ICU+JSBkcm9wX25hKCkgICU+JSBmaWx0ZXIobG9nSW5mbyE9J1VOTlVNQkVSRUQnKSwgYWVzKHg9ZmN0X2luZnJlcShsb2dJbmZvKSkpICsKICBnZW9tX2Jhcihjb2xvcj0nYmxhY2snLCBmaWxsPScjYzdkMGQ4Jyxwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCAwLjMpKSsKICBnZW9tX3RleHQoc3RhdD0nY291bnQnLCBhZXMobGFiZWw9Li5jb3VudC4uKSwgdmp1c3Q9LTEpKwogIGdlb21fdGV4dChhZXMoeD0nQkFSTEVZJywgeT0yMDAsIGxhYmVsPSdQcmVzcyAxJyksY29sb3I9J2JsYWNrJykrCiAgZ2VvbV90ZXh0KGFlcyh4PSdNQUlaRScsIHk9MjAwLCBsYWJlbD0nUHJlc3MgMicpLGNvbG9yPSdibGFjaycpKwogIGdlb21fdGV4dChhZXMoeD0nU09SR0hVTScsIHk9MjAwLCBsYWJlbD0nUHJlc3MgMycpLGNvbG9yPSdibGFjaycpKwogIGdlb21fdGV4dChhZXMoeD0nVEVGJywgeT0yMDAsIGxhYmVsPSdQcmVzcyA0JyksY29sb3I9J2JsYWNrJykrCiAgZ2VvbV90ZXh0KGFlcyh4PSdXSEVBVCcsIHk9MjAwLCBsYWJlbD0nUHJlc3MgNScpLGNvbG9yPSdibGFjaycpKwogIGdlb21fdGV4dChhZXMoeD0nU0VTQU1FJywgeT0yMDAsIGxhYmVsPSdQcmVzcyA2JyksY29sb3I9J2JsYWNrJykrCiAgZ2VvbV90ZXh0KGFlcyh4PSdGQVZBIEJFQU4nLCB5PTIwMCwgbGFiZWw9J1ByZXNzIDcnKSxjb2xvcj0nYmxhY2snKSsKICBnZW9tX3RleHQoYWVzKHg9J0NISUNLUEVBJywgeT0yMDAsIGxhYmVsPSdQcmVzcyA4JyksY29sb3I9J2JsYWNrJykrCiAgZ2VvbV90ZXh0KGFlcyh4PSdDT01NT04gQkVBTicsIHk9MjAwLCBsYWJlbD0nUHJlc3MgOScpLGNvbG9yPSdibGFjaycpKwogICNnZW9tX3RleHQoYWVzKHg9J0NPVFRPTicsIHk9MjAwLCBsYWJlbD0nUHJlc3NcbjEwJyksY29sb3I9J2JsYWNrJykrCiAgZ2VvbV90ZXh0KGFlcyh4PSdOT04tTlVNRVJJQyBLRVknLCB5PTIwMCwgbGFiZWw9J1ByZXNzICMvKicpLGNvbG9yPSdibGFjaycpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0xLGNvbG9yPSdibGFjaycpLAogICAgICAgICBwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZmNmZmY5IiksCiAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZmNmZmY5IiksCiAgICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoc2l6ZT0uMSxjb2xvdXIgPSAiYmxhY2siKSwKICAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShzaXplPS4xLGNvbG91ciA9ICJibGFjayIpLAogICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgIHBhbmVsLmdyaWQubWlub3IueCA9IGVsZW1lbnRfYmxhbmsoKSkrCiAgeWxpbSgwLDI1MDApKwogIGxhYnMoCiAgICB0aXRsZSA9ICdEaXN0cmlidXRpb24gb2YgT3B0aW9ucyBTZWxlY3RlZCcsCiAgICB4ID0gJ1JhaW4gQ3JvcCBNZW51IE9wdGlvbnMnLAogICAgeT0gJ0ZyZXF1ZW5jeScKICApCgojIGdncGxvdChkYXRhPXJhaW5fbWVudV9jYWxsLCBhZXMoeD1mY3RfaW5mcmVxKGxvZ0luZm8pKSkgKwojICAgZ2VvbV9iYXIoY29sb3I9J2JsYWNrJywgZmlsbD0nI2M3ZDBkOCcscG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSggMC4zKSkrCiMgICBnZW9tX3RleHQoc3RhdD0nY291bnQnLCBhZXMobGFiZWw9Li5jb3VudC4uKSwgdmp1c3Q9LTEpKwojICAgZ2VvbV90ZXh0KGFlcyh4PSdQUkVQTEFOVElORycsIHk9MTIwLCBsYWJlbD0nUHJlc3MgMScpLGNvbG9yPSdibGFjaycpKwojICAgZ2VvbV90ZXh0KGFlcyh4PSdQTEFOVElORycsIHk9MTIwLCBsYWJlbD0nUHJlc3MgMicpLGNvbG9yPSdibGFjaycpKwojICAgZ2VvbV90ZXh0KGFlcyh4PSdDUk9QIFBST1RFQ1RJT04nLCB5PTEyMCwgbGFiZWw9J1ByZXNzIDMnKSxjb2xvcj0nYmxhY2snKSsKIyAgIGdlb21fdGV4dChhZXMoeD0nRkVSVElMSVpFUiBEUkVTU0lORycsIHk9MTIwLCBsYWJlbD0nUHJlc3MgNCcpLGNvbG9yPSdibGFjaycpKwojICAgZ2VvbV90ZXh0KGFlcyh4PSdQT1NUIEhBUlZFU1QnLCB5PTEyMCwgbGFiZWw9J1ByZXNzIDUnKSxjb2xvcj0nYmxhY2snKSsKIyAgIGdlb21fdGV4dChhZXMoeD0nTk9OLU5VTUVSSUMgS0VZJywgeT0xMjAsIGxhYmVsPSdQcmVzcyAjLyonKSxjb2xvcj0nYmxhY2snKSsKIyAgIHlsaW0oMCwyODAwKSsKIyAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0xLGNvbG9yPSdibGFjaycpLAojICAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI2ZjZmZmOSIpLAojICAgICAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZmNmZmY5IiksCiMgICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9saW5lKHNpemU9LjEsY29sb3VyID0gImJsYWNrIiksCiMgICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKHNpemU9LjEsY29sb3VyID0gImJsYWNrIiksCiMgICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksCiMgICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnggPSBlbGVtZW50X2JsYW5rKCkpKwojICAgbGFicygKIyAgICAgdGl0bGUgPSAnRGlzdGlydXRpb24gb2YgUmFpbiBNZW51IE9wdGlvbnMgU2VsZWN0ZWQgcGVyIENhbGwgd2l0aCBDb3JyZXNwb25kaW5nIEJ1dHRvbicsCiMgICAgIHggPSAnUmFpbiBNZW51IE9wdGlvbnMnLAojICAgICB5PSdOdW1iZXIgb2YgVGltZXMgU2VsZWN0ZWQnCiMgICApCgoKCiNnZXR0aW5nIHRoZSBISEkgTUVOVQpoaGlfY3JvcF9tZW51IDwtIGZpbHRlcihsb2dfZGF0YSwgZ3JlcGwoIkhISUNST1AgTUVOVSAtICIsbG9nSW5mbykpCmhoaV9jcm9wX21lbnUkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGhoaV9jcm9wX21lbnUkbG9nSW5mbywgIkhISUNST1AgTUVOVSAtICIsICIiKQpoaGlfY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShoaGlfY3JvcF9tZW51JGxvZ0luZm8sICIgU0VMRUNURUQiLCAiIikKdGFibGUoaGhpX2Nyb3BfbWVudSRsb2dJbmZvKQoKI0FERElORyBUSEUgTlVNQkVSUwpoaGlfY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShoaGlfY3JvcF9tZW51JGxvZ0luZm8sICJQT1RBVE8gT1BUSU9OIiwgIlBPVEFUTyIpCmhoaV9jcm9wX21lbnUkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGhoaV9jcm9wX21lbnUkbG9nSW5mbywgIkNBUlJPVCBPUFRJT04iLCAiQ0FSUk9UIikKaGhpX2Nyb3BfbWVudSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoaGhpX2Nyb3BfbWVudSRsb2dJbmZvLCAiT05JT04gT1BUSU9OIiwgIk9OSU9OIikKaGhpX2Nyb3BfbWVudSRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoaGhpX2Nyb3BfbWVudSRsb2dJbmZvLCAiR0FSTElDIE9QVElPTiIsICJHQVJMSUMiKQpoaGlfY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShoaGlfY3JvcF9tZW51JGxvZ0luZm8sICJUT01BVE8gT1BUSU9OIiwgIlRPTUFUTyIpCmhoaV9jcm9wX21lbnUkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGhoaV9jcm9wX21lbnUkbG9nSW5mbywgIlBBUEVSIE9QVElPTiIsICJQRVBQRVIiKQpoaGlfY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShoaGlfY3JvcF9tZW51JGxvZ0luZm8sICJIRUFEIENBQkJBR0UgT1BUSU9OIiwgIkhFQUQgQ0FCQkFHRSIpCmhoaV9jcm9wX21lbnUkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGhoaV9jcm9wX21lbnUkbG9nSW5mbywgIkNST1AgTUVOVSBSRVBMQVlFRCIsICJOT04tTlVNRVJJQyBLRVkiKQpoaGlfY3JvcF9tZW51JGxvZ0luZm88LSBzdHJfcmVwbGFjZShoaGlfY3JvcF9tZW51JGxvZ0luZm8sICJHTyBUTyBNQUlOIE1FTlUgT1BUSU9OIiwgIk5PTi1OVU1FUklDIEtFWSIpCmhoaV9jcm9wX21lbnUkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGhoaV9jcm9wX21lbnUkbG9nSW5mbywgIklOVkFMSUQgS0VZIFBSRVNTRUQiLCAiTk9OLU5VTUVSSUMgS0VZIikKCiNwbG90dGluZyBISEkKZ2dwbG90KGhoaV9jcm9wX21lbnUsIGFlcyh4PWZjdF9pbmZyZXEobG9nSW5mbykpKSArCiAgZ2VvbV9iYXIoY29sb3I9J2JsYWNrJywgZmlsbD0nIzE5NzIzZicscG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSggMC4zKSkrCiAgZ2VvbV90ZXh0KHN0YXQ9J2NvdW50JywgYWVzKGxhYmVsPS4uY291bnQuLiksIHZqdXN0PS0xKSsKICBnZW9tX3RleHQoYWVzKHg9J1BPVEFUTycsIHk9NzAsIGxhYmVsPSdQcmVzcyAxJyksY29sb3I9JyNmY2ZmZjknKSsKICBnZW9tX3RleHQoYWVzKHg9J0NBUlJPVCcsIHk9NzAsIGxhYmVsPSdQcmVzcyAyJyksY29sb3I9JyNmY2ZmZjknKSsKICBnZW9tX3RleHQoYWVzKHg9J09OSU9OJywgeT03MCwgbGFiZWw9J1ByZXNzIDMnKSxjb2xvcj0nI2ZjZmZmOScpKwogIGdlb21fdGV4dChhZXMoeD0nR0FSTElDJywgeT03MCwgbGFiZWw9J1ByZXNzIDQnKSxjb2xvcj0nI2ZjZmZmOScpKwogIGdlb21fdGV4dChhZXMoeD0nVE9NQVRPJywgeT03MCwgbGFiZWw9J1ByZXNzIDUnKSxjb2xvcj0nI2ZjZmZmOScpKwogIGdlb21fdGV4dChhZXMoeD0nUEVQUEVSJywgeT03MCwgbGFiZWw9J1ByZXNzIDYnKSxjb2xvcj0nI2ZjZmZmOScpKwogIGdlb21fdGV4dChhZXMoeD0nSEVBRCBDQUJCQUdFJywgeT03MCwgbGFiZWw9J1ByZXNzIDcnKSxjb2xvcj0nI2ZjZmZmOScpKwogIGdlb21fdGV4dChhZXMoeD0nTk9OLU5VTUVSSUMgS0VZJywgeT03MCwgbGFiZWw9J1ByZXNzICMvKicpLGNvbG9yPScjZmNmZmY5JykrCiAgeWxpbSgwLDE3NTApKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzAsIGhqdXN0ID0xKSwKICAgICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI2ZjZmZmOSIpLAogICAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNmY2ZmZjkiKSwKICAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZShzaXplPS4xLGNvbG91ciA9ICJibGFjayIpLAogICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKHNpemU9LjEsY29sb3VyID0gImJsYWNrIiksCiAgICAgICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpKSsKICBsYWJzKAogICAgdGl0bGUgPSAnRGlzdHJpYnV0aW9uIG9mIE9wdGlvbnMgU2VsZWN0ZWQnLAogICAgeCA9ICdISEkgQ3JvcCBNZW51IE9wdGlvbnMnLAogICAgeT0gJ0ZyZXF1ZW5jeScKICApCgoKCmBgYAoKCmBgYHtyfQoKIyBUT1RBTCBDUk9QUyBCWSBDT05FTlQgUExBWUVERSBFVkVSISEhIQpjb250ZW50X2Nyb3BfcGxheWVkIDwtIGZpbHRlcihsb2dfZGF0YSwgZ3JlcGwoIkNPTlRFTlQgUExBWUVEIC0gIixsb2dJbmZvKSkKY29udGVudF9jcm9wX3BsYXllZCA8LSBmaWx0ZXIoY29udGVudF9jcm9wX3BsYXllZCwgIWdyZXBsKCJMSVZFU1RPQ0siLGxvZ0luZm8pKQpjb250ZW50X2Nyb3BfcGxheWVkIDwtIGZpbHRlcihjb250ZW50X2Nyb3BfcGxheWVkLCAhZ3JlcGwoIkFQSUNVTFRVUkUiLGxvZ0luZm8pKQpjb250ZW50X2Nyb3BfcGxheWVkIDwtIGZpbHRlcihjb250ZW50X2Nyb3BfcGxheWVkLCAhZ3JlcGwoIkNPVklEIixsb2dJbmZvKSkKY29udGVudF9jcm9wX3BsYXllZCA8LSBmaWx0ZXIoY29udGVudF9jcm9wX3BsYXllZCwgIWdyZXBsKCJEQUlSWSIsbG9nSW5mbykpCmNvbnRlbnRfY3JvcF9wbGF5ZWQgPC0gZmlsdGVyKGNvbnRlbnRfY3JvcF9wbGF5ZWQsICFncmVwbCgiRkFNSUxZIixsb2dJbmZvKSkKY29udGVudF9jcm9wX3BsYXllZCA8LSBmaWx0ZXIoY29udGVudF9jcm9wX3BsYXllZCwgIWdyZXBsKCJDQVRUTEUiLGxvZ0luZm8pKQpjb250ZW50X2Nyb3BfcGxheWVkIDwtIGZpbHRlcihjb250ZW50X2Nyb3BfcGxheWVkLCAhZ3JlcGwoIkZBVFRFTklORyIsbG9nSW5mbykpCmNvbnRlbnRfY3JvcF9wbGF5ZWQgPC0gZmlsdGVyKGNvbnRlbnRfY3JvcF9wbGF5ZWQsICFncmVwbCgiUE9VTFRSWSIsbG9nSW5mbykpCmNvbnRlbnRfY3JvcF9wbGF5ZWQgPC0gZmlsdGVyKGNvbnRlbnRfY3JvcF9wbGF5ZWQsICFncmVwbCgiU0FGRSIsbG9nSW5mbykpCmNvbnRlbnRfY3JvcF9wbGF5ZWQgPC0gZmlsdGVyKGNvbnRlbnRfY3JvcF9wbGF5ZWQsICFncmVwbCgiTUlTQ09OQ0VQVElPTlMiLGxvZ0luZm8pKQoKI2dldHRpbmcgcmlkIG9mIHRoZSBsYW5ndWFnZXMvY29udGVudApjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICItIEFNSEFSSUMiLCAiIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiLSBPUk9NSUZGQSIsICIiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICItIFRJR1JJR05BIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIi0gV09MQVlJVFRBIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIi0gV09MQVlUSUdOQSIsICIiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICItIFNJREFNSUdOQSIsICIiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJDT05URU5UIFBMQVlFRCAtICIsICIiKQoKI2dldHRpbmcgcmlkIG9mIG1lbnUgbGFiZWxzCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIkFQUExZSU5HIEZFUlRJTElaRVIgLSAiLCAiIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiRElTRUFTRSBDT05UUk9MIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIkZFUlRJTElaRVIgQVBQTElDQVRJT04gUkFURSAtICIsICIiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJGRVJUSUxJWkVSIFNJREUgRFJFU1NJTkcgLSAiLCAiIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiSEFSUk9XSU5HIEFORCBFQVJUSE5JTkcgVVAgLSAiLCAiIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiSEFSVkVTVElORyAtICIsICIiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJIQVJWRVNUSU5HIFRFQ0hOSVFVRSAtICIsICIiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJIT1cgVE8gQUREIFdBVEVSIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIkhPVyBUTyBQTEFOVCAtICIsICIiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJIT1cgVE8gU0VMRUNUIEFORCBCVVkgU0VFRFMgLSAiLCAiIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiSU5TRUNUIENPTlRST0wgLSAiLCAiIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiTEFORCBQUkVQQVJBVElPTiAtICIsICIiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJNQU5BR0lORyBXRUVEUyAtICIsICIiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJNT0lTVFVSRSBDT05TRVJWQVRJT04gLSAiLCAiIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiT1BUSU1VTSBTUEFDSU5HIEJFVFdFRU4gUk9XUyBBTkQgUExBTlRTIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIlBMT1QgUFJFUEFSQVRJT04gLSAiLCAiIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiUFJFLUlSUklHQVRJT04gLSAiLCAiIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiUFJPQ0VTU0lORyAtICIsICIiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJcXCgiLCAiIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiXFwpIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIlBST0NFU1NJTkcgSEhJIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIlBST1RFQ1RJT04gT04gSU5TRUNUUyBBTkQgRElTRUFTRVMgLSAiLCAiIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiU0VFRCBSQVRFIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIlNFRUQgVkFSSVRZIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIlNFRUQgVkFSSVRZIC0iLCAiIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiU09JTCBERVBUSCAtICIsICIiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJTT0lMIERFUFRIIC0iLCAiIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiVEhSRVNISU5HIEFORCBDTEVBTklORyAtICIsICIiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJUUkFOU1BMQU5USU5HIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIldFRUQgQ09OVFJPTCAtICIsICIiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJXSEVOIEFORCBIT1cgTVVDSCBXQVRFUiBUTyBBREQgLSBERUdBIC0gQ0xBWSAtICIsICIiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJIRU4gQU5EIEhPVyBNVUNIIFdBVEVSIFRPIEFERCAtIERFR0EgLSBMT0FNIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIldIRU4gQU5EIEhPVyBNVUNIIFdBVEVSIFRPIEFERCAtIEtPTEEgLSBDTEFZIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIldIRU4gQU5EIEhPVyBNVUNIIFdBVEVSIFRPIEFERCAtIEtPTEEgLSBTQU5EIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIldIRU4gQU5EIEhPVyBNVUNIIFdBVEVSIFRPIEFERCAtIERFR0EgLSBTQU5EIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIldIRU4gQU5EIEhPVyBNVUNIIFdBVEVSIFRPIEFERCAtIEtPTEEgLSBMT0FNIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIldIRU4gQU5EIEhPVyBNVUNIIFdBVEVSIFRPIEFERCAtIFdPWUVOQURFR0EgLSBDTEFZIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIldIRU4gQU5EIEhPVyBNVUNIIFdBVEVSIFRPIEFERCAtIFdPWUVOQURFR0EgLSBMT0FNIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIldIRU4gQU5EIEhPVyBNVUNIIFdBVEVSIFRPIEFERCAtIFdPWUVOQURFR0EgLSBTQU5EIC0gIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIldIRU4gVE8gSEFSVkVTVCAtICIsICIiKQoKI2ZpeGluZyBleHRyYSBjaGFuZ2VzCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlX2FsbChjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICIgIiwgIiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlX2FsbChjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJXQyIsICJDIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2VfYWxsKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIldHIiwgIkciKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZV9hbGwoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiV08iLCAiTyIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlX2FsbChjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJXUCIsICJQIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2VfYWxsKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIldUIiwgIlQiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZV9hbGwoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiV0hFQURDQUJCQUdFIiwgIkhFQURDQUJCQUdFIikKCiNBRERJTkcgVEhFIE5VTUJFUlMKI0FERElORyBUSEUgTlVNQkVSUwpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJQT1RBVE8iLCAiMSAtIFBPVEFUTyIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIkNBUlJPVCIsICIyIC0gQ0FSUk9UIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiT05JT04iLCAiMyAtIE9OSU9OIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiR0FSTElDIiwgIjQgLSBHQVJMSUMiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJUT01BVE8iLCAiNSAtIFRPTUFUTyIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIlBFUFBFUiIsICI2IC0gUEVQUEVSIE9QVElPTiIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIkhFQURDQUJCQUdFIiwgIjcgLSBIRUFEIENBQkJBR0UiKQoKCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIkJBUkxFWSIsICIxIC0gQkFSTEVZIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiTUFJWkUiLCAiMiAtIE1BSVpFIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiU09SR0hVTSIsICIzIC0gU09SR0hVTSIpCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIlRFRiIsICI0IC0gVEVGIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiV0hFQVQiLCAiNSAtIFdIRUFUIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiU0VTQU1FIiwgIjYgLSBTRVNBTUUiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJGQVZBIEJFQU5TIiwgIjcgLSBGQVZBIEJFQU4iKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJDSElDS1BFQSIsICI4IC0gQ0hJQ0tQRUEiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJDT01NT05CRUFOUyIsICI5IC0gQ09NTU9OIEJFQU5TIikKY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY29udGVudF9jcm9wX3BsYXllZCRsb2dJbmZvLCAiQ09UVE9OIiwgIjEwIC0gQ09UVE9OIikKCmNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNvbnRlbnRfY3JvcF9wbGF5ZWQkbG9nSW5mbywgIkRVUkFNRTUgLSBXSEVBVCIsICJEVVJBTUUgV0hFQVQiKQpjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjb250ZW50X2Nyb3BfcGxheWVkJGxvZ0luZm8sICJNQUxUMSAtIEJBUkxFWSIsICJNQUxUIEJBUkxFWSIpCgoKCj9nZW9tX3RleHQKZ2dwbG90KGNvbnRlbnRfY3JvcF9wbGF5ZWQsIGFlcyh4PWZjdF9pbmZyZXEobG9nSW5mbykpKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA2MCwgaGp1c3QgPTEsIHNpemUgPSA3KSkrCiAgZ2VvbV9iYXIoZmlsbD0nc2t5IGJsdWUnKSsKICBnZW9tX3RleHQoc3RhdD0nY291bnQnLCBhZXMobGFiZWw9Li5jb3VudC4uKSwgdmp1c3Q9LTEsc2l6ZT0zKSsKICB5bGltKDAsMjc1MCkrCiAgbGFicygKICAgIHRpdGxlID0gJ0FMTCBDcm9wcyBFdmVyIEFjY2Vzc2VkIEFjcm9zcyBBbGwgQ2FsbHMgd2l0aCBMYWJlbGVkIEJ1dHRvbnMnLAogICAgeCA9ICdDcm9wcycsCiAgICB5PSAnY291bnQnCiAgKQpgYGAKCgoKCgojV2hhdCBhYm91dCBhIG5pY2UgY3JvcCBicmVha2Rvd24gcGVyIG1vbnRoPwpgYGB7cn0KCmNyb3BfbW9udGggPC0gbG9nX2RhdGEgJT4lCiAgZmlsdGVyKGdyZXBsKCJDUk9QIE1FTlUgLSAiLGxvZ0luZm8pKSAlPiUKICBmaWx0ZXIoIWdyZXBsKCJISEkiLGxvZ0luZm8pKSAlPiUKICBmaWx0ZXIoIWdyZXBsKCJSRVBMQVlFRCIsbG9nSW5mbykpCgpjcm9wX21vbnRoIDwtIGNyb3BfbW9udGggJT4lCiAgZ3JvdXBfYnkoY2FsbGVySWQsIGxvZ0luZm8sbW9udGgpICU+JQogIGNvdW50KCkKCmNyb3BfbW9udGgkbG9nSW5mbzwtIHN0cl9yZXBsYWNlKGNyb3BfbW9udGgkbG9nSW5mbywgIkNST1AgTUVOVSAtICIsICIiKQpjcm9wX21vbnRoJGxvZ0luZm88LSBzdHJfcmVwbGFjZShjcm9wX21vbnRoJGxvZ0luZm8sICIgU0VMRUNURUQiLCAiIikKY3JvcF9tb250aCRsb2dJbmZvPC0gc3RyX3JlcGxhY2UoY3JvcF9tb250aCRsb2dJbmZvLCAiR08gVE8iLCAiIikKCgpjcm9wX3RyYWNrIDwtIGNyb3BfbW9udGggJT4lCiAgZmlsdGVyKG1vbnRoID09IDEpCmdncGxvdChjcm9wX3RyYWNrLCBhZXMoeD1sb2dJbmZvKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNjAsIGhqdXN0ID0xLCBzaXplID0gNykpKwogIGdlb21fYmFyKCkrCiAgbGFicygKICAgIHRpdGxlID0gJ0Nyb3AgbWVudSBicmVha2Rvd24gSmFuJywKICAgIHggPSAnQ3JvcHMnLAogICAgeT0gJ2NvdW50JwogICkKICAKY3JvcF90cmFjayA8LSBjcm9wX21vbnRoICU+JQogIGZpbHRlcihtb250aCA9PSAyKQpnZ3Bsb3QoY3JvcF90cmFjaywgYWVzKHg9bG9nSW5mbykpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDYwLCBoanVzdCA9MSwgc2l6ZSA9IDcpKSsKICBnZW9tX2JhcigpKwogIGxhYnMoCiAgICB0aXRsZSA9ICdDcm9wIG1lbnUgYnJlYWtkb3duIGZlYicsCiAgICB4ID0gJ0Nyb3BzJywKICAgIHk9ICdjb3VudCcKICApCmNyb3BfdHJhY2sgPC0gY3JvcF9tb250aCAlPiUKICBmaWx0ZXIobW9udGggPT0gMykKZ2dwbG90KGNyb3BfdHJhY2ssIGFlcyh4PWxvZ0luZm8pKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA2MCwgaGp1c3QgPTEsIHNpemUgPSA3KSkrCiAgZ2VvbV9iYXIoKSsKICBsYWJzKAogICAgdGl0bGUgPSAnQ3JvcCBtZW51IGJyZWFrZG93biBtYXInLAogICAgeCA9ICdDcm9wcycsCiAgICB5PSAnY291bnQnCiAgKQpjcm9wX3RyYWNrIDwtIGNyb3BfbW9udGggJT4lCiAgZmlsdGVyKG1vbnRoID09IDQpCmdncGxvdChjcm9wX3RyYWNrLCBhZXMoeD1sb2dJbmZvKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNjAsIGhqdXN0ID0xLCBzaXplID0gNykpKwogIGdlb21fYmFyKCkrCiAgbGFicygKICAgIHRpdGxlID0gJ0Nyb3AgbWVudSBicmVha2Rvd24gYXByaWwnLAogICAgeCA9ICdDcm9wcycsCiAgICB5PSAnY291bnQnCiAgKQpjcm9wX3RyYWNrIDwtIGNyb3BfbW9udGggJT4lCiAgZmlsdGVyKG1vbnRoID09IDUpCmdncGxvdChjcm9wX3RyYWNrLCBhZXMoeD1sb2dJbmZvKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNjAsIGhqdXN0ID0xLCBzaXplID0gNykpKwogIGdlb21fYmFyKCkrCiAgbGFicygKICAgIHRpdGxlID0gJ0Nyb3AgbWVudSBicmVha2Rvd24gbWF5JywKICAgIHggPSAnQ3JvcHMnLAogICAgeT0gJ2NvdW50JwogICkKY3JvcF90cmFjayA8LSBjcm9wX21vbnRoICU+JQogIGZpbHRlcihtb250aCA9PSA2KQpnZ3Bsb3QoY3JvcF90cmFjaywgYWVzKHg9bG9nSW5mbykpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDYwLCBoanVzdCA9MSwgc2l6ZSA9IDcpKSsKICBnZW9tX2JhcigpKwogIGxhYnMoCiAgICB0aXRsZSA9ICdDcm9wIG1lbnUgYnJlYWtkb3duIGp1bmUnLAogICAgeCA9ICdDcm9wcycsCiAgICB5PSAnY291bnQnCiAgKQpjcm9wX3RyYWNrIDwtIGNyb3BfbW9udGggJT4lCiAgZmlsdGVyKG1vbnRoID09IDcpCmdncGxvdChjcm9wX3RyYWNrLCBhZXMoeD1sb2dJbmZvKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNjAsIGhqdXN0ID0xLCBzaXplID0gNykpKwogIGdlb21fYmFyKCkrCiAgbGFicygKICAgIHRpdGxlID0gJ0Nyb3AgbWVudSBicmVha2Rvd24ganVseScsCiAgICB4ID0gJ0Nyb3BzJywKICAgIHk9ICdjb3VudCcKICApCmNyb3BfdHJhY2sgPC0gY3JvcF9tb250aCAlPiUKICBmaWx0ZXIobW9udGggPT0gOCkKZ2dwbG90KGNyb3BfdHJhY2ssIGFlcyh4PWxvZ0luZm8pKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA2MCwgaGp1c3QgPTEsIHNpemUgPSA3KSkrCiAgZ2VvbV9iYXIoKSsKICBsYWJzKAogICAgdGl0bGUgPSAnQ3JvcCBtZW51IGJyZWFrZG93biBhdWcnLAogICAgeCA9ICdDcm9wcycsCiAgICB5PSAnY291bnQnCiAgKQpjcm9wX3RyYWNrIDwtIGNyb3BfbW9udGggJT4lCiAgZmlsdGVyKG1vbnRoID09IDkpCmdncGxvdChjcm9wX3RyYWNrLCBhZXMoeD1sb2dJbmZvKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNjAsIGhqdXN0ID0xLCBzaXplID0gNykpKwogIGdlb21fYmFyKCkrCiAgbGFicygKICAgIHRpdGxlID0gJ0Nyb3AgbWVudSBicmVha2Rvd24gc2VwJywKICAgIHggPSAnQ3JvcHMnLAogICAgeT0gJ2NvdW50JwogICkKY3JvcF90cmFjayA8LSBjcm9wX21vbnRoICU+JQogIGZpbHRlcihtb250aCA9PSAxMCkKZ2dwbG90KGNyb3BfdHJhY2ssIGFlcyh4PWxvZ0luZm8pKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA2MCwgaGp1c3QgPTEsIHNpemUgPSA3KSkrCiAgZ2VvbV9iYXIoKSsKICBsYWJzKAogICAgdGl0bGUgPSAnQ3JvcCBtZW51IGJyZWFrZG93biBvY3QnLAogICAgeCA9ICdDcm9wcycsCiAgICB5PSAnY291bnQnCiAgKQpjcm9wX3RyYWNrIDwtIGNyb3BfbW9udGggJT4lCiAgZmlsdGVyKG1vbnRoID09IDExKQpnZ3Bsb3QoY3JvcF90cmFjaywgYWVzKHg9bG9nSW5mbykpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDYwLCBoanVzdCA9MSwgc2l6ZSA9IDcpKSsKICBnZW9tX2JhcigpKwogIGxhYnMoCiAgICB0aXRsZSA9ICdDcm9wIG1lbnUgYnJlYWtkb3duIG5vdicsCiAgICB4ID0gJ0Nyb3BzJywKICAgIHk9ICdjb3VudCcKICApCmNyb3BfdHJhY2sgPC0gY3JvcF9tb250aCAlPiUKICBmaWx0ZXIobW9udGggPT0gMTIpCmdncGxvdChjcm9wX3RyYWNrLCBhZXMoeD1sb2dJbmZvKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNjAsIGhqdXN0ID0xLCBzaXplID0gNykpKwogIGdlb21fYmFyKCkrCiAgbGFicygKICAgIHRpdGxlID0gJ0Nyb3AgbWVudSBicmVha2Rvd24gZGVjJywKICAgIHggPSAnQ3JvcHMnLAogICAgeT0gJ2NvdW50JwogICkKCgpgYGAKCg==